क्या #pragma में एक बार तिजोरी शामिल है?


310

मैंने पढ़ा है कि उपयोग करते समय कुछ संकलक अनुकूलन होता है #pragma onceजिसके परिणामस्वरूप तेज संकलन हो सकता है। मैं पहचानता हूं कि यह गैर-मानक है, और इस तरह क्रॉस-प्लेटफॉर्म संगतता समस्या पैदा कर सकता है।

क्या यह ऐसी चीज़ है जो गैर-विंडोज़ प्लेटफ़ॉर्म (gcc) पर अधिकांश आधुनिक कंपाइलरों द्वारा समर्थित है?

मैं प्लेटफ़ॉर्म संकलन मुद्दों से बचना चाहता हूं, लेकिन साथ ही साथ कमबैक गार्ड के अतिरिक्त काम से बचना चाहता हूं:

#pragma once
#ifndef HEADER_H
#define HEADER_H

...

#endif // HEADER_H

क्या मुझे चिंतित होना चाहिए? क्या मुझे इस पर कोई और मानसिक ऊर्जा खर्च करनी चाहिए?


3
इसी तरह का सवाल पूछने के बाद , मुझे पता चला कि #pragma onceवीएस 2008 में कुछ वर्ग दृश्य मुद्दों से बचने के लिए प्रतीत होता है। मैं शामिल गार्ड से छुटकारा पाने और #pragma onceइस कारण से उन सभी को बदलने की प्रक्रिया में हूं ।
13

जवाबों:


188

उपयोग #pragma onceकरना किसी भी आधुनिक संकलक पर काम करना चाहिए, लेकिन मुझे कोई कारण नहीं दिखता है कि मानक का उपयोग न करें #ifndefगार्ड शामिल हैं। यह ठीक काम करता है। एक चेतावनी यह है कि संस्करण 3.4#pragma once से पहले GCC ने समर्थन नहीं किया था ।

मैंने यह भी पाया कि, कम से कम जीसीसी पर, यह मानक को पहचानता है कि #ifndefइसमें गार्ड भी शामिल है और इसे अनुकूलित करता है , इसलिए इसे इससे अधिक धीमा नहीं होना चाहिए #pragma once


12
यह किसी भी तरह (जीसीसी के साथ) बिल्कुल भी धीमा नहीं होना चाहिए।
जेसन कोको

54
यह उस तरह से लागू नहीं है। इसके बजाय, यदि फ़ाइल पहली बार #ifndef से शुरू होती है और एक #endif के साथ समाप्त होती है, तो gcc इसे याद रखता है और हमेशा उस स्किप को शामिल करता है, जो भविष्य में फ़ाइल को खोलने के लिए परेशान किए बिना भी शामिल होता है।
जेसन कोको

10
#pragma onceआम तौर पर तेज है क्योंकि फ़ाइल प्रीप्रोसेस नहीं की जा रही है। ifndef/define/endifवैसे भी प्रीप्रोसेसिंग की आवश्यकता होती है, क्योंकि इस ब्लॉक के बाद आपके पास कुछ अनिवार्य (सैद्धांतिक रूप से) हो सकता है
एंड्री

13
गार्ड मैक्रो ऑप्टिमाइज़ेशन पर GCC डॉक्स: gcc.gnu.org/oniltocs/cppinternals/Guard-Macros.html
एड्रियन

38
गार्ड को शामिल करने के लिए, अतिरिक्त आवश्यकता है कि आपको एक नया प्रतीक परिभाषित करना होगा #ifndef FOO_BAR_H, जैसे कि आम तौर पर "foo_bar.h" फ़ाइल के लिए। यदि आप बाद में इस फ़ाइल का नाम बदलते हैं, तो क्या आपको इस सम्मेलन के अनुरूप होने के लिए शामिल गार्ड को समायोजित करना चाहिए? इसके अलावा, यदि आपके दो अलग-अलग foo_bar.h आपके कोड ट्री में दो अलग-अलग स्थानों पर हैं, तो आपको हर एक के लिए दो अलग-अलग प्रतीकों के बारे में सोचना होगा। संक्षिप्त उत्तर का उपयोग करना है #pragma onceऔर यदि आपको वास्तव में ऐसे वातावरण में संकलन करने की आवश्यकता है जो इसका समर्थन नहीं करता है, तो आगे बढ़ें और उस वातावरण के लिए गार्ड शामिल करें।
ब्रैंडिन

327

#pragma once इसमें एक खामी है (गैर-मानक होने के अलावा) और यदि आपके पास अलग-अलग स्थानों में एक ही फाइल है (हमारे पास यह है क्योंकि हमारी बिल्ड सिस्टम फाइलों को कॉपी करती है) तो कंपाइलर सोचेंगे कि ये अलग-अलग फाइलें हैं।


36
लेकिन आप अलग-अलग स्थानों में एक ही नाम के साथ दो फाइलें रख सकते हैं, बिना अलग-अलग #define NAMES बनाए परेशान होना, जो कि HEADERFILENAME_H के रूप में अलग है
वर्गास

69
आपके पास एक ही #define WHATEVER के साथ दो या अधिक फाइलें भी हो सकती हैं, जो मस्ती का कोई अंत नहीं है, यही कारण है कि मैं एक बार प्रज्ञा का उपयोग करने का पक्ष लूंगा।
क्रिस हुआंग-लीवर

107
प्रेरक नहीं ... बिल्ड सिस्टम को एक में बदलें, जो फाइलों को चारों ओर से कॉपी नहीं करता है, बल्कि इसके बजाय सीमलिंक का उपयोग करता है, या प्रत्येक ट्रांसलेशन यूनिट में केवल एक ही स्थान से एक ही फाइल शामिल करता है। आपके बुनियादी ढांचे की तरह लगता है कि एक गड़बड़ है जिसे पुनर्गठित किया जाना है।
याकोव गल्का

3
और अगर आपके पास अलग-अलग निर्देशिकाओं पर एक ही नाम के साथ अलग-अलग फाइलें हैं, तो #ifdef दृष्टिकोण सोचेंगे कि वे एक ही फाइल हैं। तो एक के लिए एक खामी है, और दूसरे के लिए एक खामी है।
rxantos

3
@rxantos, यदि फ़ाइलें भिन्न होती हैं तो #ifdefमैक्रो मान भी भिन्न हो सकता है।
मोति

63

काश #pragma once(या ऐसा कुछ) मानक में होता। गार्ड को शामिल करना एक वास्तविक बड़ी बात नहीं है (लेकिन उन्हें भाषा सीखने वाले लोगों को समझाना थोड़ा मुश्किल लगता है), लेकिन यह एक छोटी सी झुंझलाहट की तरह लगता है जिसे टाला जा सकता था।

वास्तव में, 99.98% समय के बाद से, #pragma onceव्यवहार वांछित व्यवहार है, अच्छा होता अगर हेडर के कई समावेशन को रोकने के लिए संकलक द्वारा स्वचालित रूप से संभाला जाता था, #pragmaजिसमें डबल सहित अनुमति देने के लिए एक या कुछ और होता है।

लेकिन हमारे पास वह है जो हमारे पास है (इसके अलावा आपके पास नहीं हो सकता है #pragma once)।


48
मैं वास्तव में जो चाहता हूं वह एक मानक #importनिर्देश है।
जॉन

10
एक मानक आयात निर्देश आ रहा है: isocpp.org/blog/2012/11/… लेकिन अभी तक यहां नहीं है। मैं इसके समर्थन में दृढ़ता से हूं।
हेल्प्स

6
@ हेल्प्स वेपरवेयर। क्या अब लगभग पांच साल हो गए हैं। शायद 2023 में आप इस टिप्पणी पर वापस आएंगे और कहेंगे "मैंने आपको ऐसा कहा"।
doug65536

यह वाष्पशील नहीं है, लेकिन यह केवल तकनीकी विनिर्देश चरण में है। मॉड्यूल विजुअल स्टूडियो 2015 (में लागू किया जाता है blogs.msdn.microsoft.com/vcblog/2015/12/03/... () और बजना में clang.llvm.org/docs/Modules.html )। और यह आयात है, # आयात नहीं।
हेल्प्स

इसे C ++ 20 में बनाना चाहिए।
आयनोकॉस्ट ब्रिघम

36

मैं किसी भी प्रदर्शन लाभ के बारे में नहीं जानता, लेकिन यह निश्चित रूप से काम करता है। मैं अपने सभी सी ++ प्रोजेक्ट्स में इसका उपयोग करता हूं (मुझे लगता है कि मैं एमएस कंपाइलर का उपयोग कर रहा हूं)। मुझे इसका उपयोग करने की तुलना में अधिक प्रभावी होना चाहिए

#ifndef HEADERNAME_H
#define HEADERNAME_H
...
#endif

यह एक ही काम करता है और अतिरिक्त मैक्रो के साथ प्रीप्रोसेसर को आबाद नहीं करता है।

जीसीसी #pragma onceआधिकारिक तौर पर संस्करण 3.4 के रूप में समर्थन करता है ।


25

#pragma once3.4 के बाद से जीसीसी सपोर्ट करता है, आगे कंपाइलर सपोर्ट के लिए http://en.wikipedia.org/wiki/Pragma_once देखें ।

#pragma onceगार्ड को शामिल करने के विरोध के रूप में उपयोग करने पर मैं जो बड़ा उलटा देखता हूं वह कॉपी / पेस्ट त्रुटियों से बचने के लिए है।

आइए इसका सामना करते हैं: हम में से अधिकांश शायद ही खरोंच से एक नई हेडर फ़ाइल शुरू करते हैं, बल्कि सिर्फ एक मौजूदा कॉपी करते हैं और इसे हमारी जरूरतों के लिए संशोधित करते हैं। इसमें #pragma onceशामिल गार्डों के बजाय कार्यशील टेम्पलेट बनाना बहुत आसान है । जितना कम मुझे टेम्पलेट को संशोधित करना होगा, उतना ही कम मैं त्रुटियों में भाग सकता हूं। समान होने से विभिन्न फ़ाइलों में गार्ड में अजीब संकलक त्रुटियां होती हैं और यह पता लगाने में कुछ समय लगता है कि क्या गलत हुआ।

TL; DR: #pragma onceउपयोग करने के लिए आसान है।


11

मैं इसका उपयोग करता हूं और मैं इससे खुश हूं, क्योंकि मुझे एक नया हेडर बनाने के लिए बहुत कम टाइप करना है। इसने मेरे लिए तीन प्लेटफार्मों में काम किया: विंडोज, मैक और लिनक्स।

मेरे पास कोई प्रदर्शन जानकारी नहीं है, लेकिन मेरा मानना ​​है कि #pragma और शामिल गार्ड के बीच अंतर C ++ व्याकरण को पार्स करने की सुस्ती की तुलना में कुछ भी नहीं होगा। यही असली समस्या है। उदाहरण के लिए C # कंपाइलर के साथ समान संख्या में फ़ाइलों और लाइनों को संकलित करने का प्रयास करें, अंतर देखने के लिए।

अंत में, गार्ड या प्रज्ञा का उपयोग करना, बिल्कुल भी मायने नहीं रखेगा।


मैं एक बार #pragma को नापसंद करता हूं, लेकिन मैं आपको सापेक्ष लाभों की ओर इशारा करते हुए सराहना करता हूं ... "सामान्य" ऑपरेटिंग वातावरण में सी ++ पार्सिंग किसी भी चीज की तुलना में बहुत अधिक महंगा है। कोई भी एक दूरस्थ फाइल सिस्टम से संकलन नहीं करता है यदि संकलन-बार एक मुद्दा है।
टॉम

1
पुनः सी ++ पार्सिंग धीमहि बनाम सी #। C # में आपको प्रत्येक छोटे + ++ फ़ाइल के लिए हेडर फ़ाइलों (iostream, किसी को?) के हजारों LOC (शाब्दिक) पार्स करने की आवश्यकता नहीं है। इस समस्या को छोटा करने के लिए पहले से तैयार किए गए हेडर का उपयोग करें, हालांकि
एली बेंडरस्की

11

' #pragma once' का उपयोग करने का कोई प्रभाव नहीं हो सकता है (यह हर जगह समर्थित नहीं है - हालांकि यह तेजी से व्यापक रूप से समर्थित है), इसलिए आपको सशर्त संकलन कोड का उपयोग करने की आवश्यकता है, वैसे भी, ' #pragma once' के साथ परेशान क्यों ? कंपाइलर शायद वैसे भी इसका अनुकूलन करता है। यह आपके लक्ष्य प्लेटफार्मों पर निर्भर करता है, हालांकि। यदि आपके सभी लक्ष्य इसका समर्थन करते हैं, तो आगे बढ़ें और इसका उपयोग करें - लेकिन यह एक सचेत निर्णय होना चाहिए क्योंकि सभी नरक ढीले हो जाएंगे यदि आप केवल प्राग्म का उपयोग करते हैं और फिर एक संकलक को पोर्ट करते हैं जो इसका समर्थन नहीं करता है।


1
मैं असहमत हूं कि आपको वैसे भी गार्ड का समर्थन करना होगा। यदि आप एक बार (या गार्ड) # प्रागमा का उपयोग करते हैं तो यह है क्योंकि यह उनके बिना कुछ संघर्षों को जन्म देता है। तो अगर यह आपके चेन टूल द्वारा समर्थित नहीं है, तो प्रोजेक्ट केवल संकलित नहीं करेगा और आप ठीक उसी तरह की स्थिति में हैं, जब आप किसी पुराने K & R कंपाइलर पर कुछ asi C संकलित करना चाहते हैं। आपको बस कुछ गार्ड जोड़ने के लिए डेट ऑफ चैंटल या चेंज कोड प्राप्त करना होगा। यदि कार्यक्रम संकलित हो रहा था लेकिन काम करने में विफल रहा तो सभी नरक तोड़ दिए जाएंगे।
क्रिश

5

प्रदर्शन का लाभ फ़ाइल को फिर से खोलने के लिए नहीं है, जब #pragma एक बार पढ़ा गया हो। गार्ड के साथ, संकलक को यह जानकारी प्राप्त करने के लिए फ़ाइल को खोलना पड़ता है (जो समय में महंगा हो सकता है) कि इसमें फिर से शामिल नहीं होना चाहिए।

यह केवल सिद्धांत है क्योंकि कुछ संकलक स्वचालित रूप से उन फ़ाइलों को नहीं खोलेंगे जिनके पास प्रत्येक संकलन इकाई के लिए कोई रीड कोड नहीं है।

वैसे भी, यह सभी कंपाइलरों के लिए नहीं है, इसलिए आदर्श रूप से #pragma को एक बार क्रॉस-प्लेटफ़ॉर्म कोड के लिए टाला जाना चाहिए, यह बिल्कुल भी मानक नहीं है / इसकी कोई मानकीकृत परिभाषा और प्रभाव नहीं है। हालांकि, व्यावहारिक रूप से, यह वास्तव में गार्ड से बेहतर है।

अंत में, बेहतर सुझाव आप प्राप्त कर सकते हैं है कि आप इस मामले में प्रत्येक संकलक के व्यवहार की जांच किए बिना अपने कंपाइलर से सबसे अच्छी गति सुनिश्चित , एक बार प्रज्ञा और गार्ड दोनों का उपयोग करना है।

#ifndef NR_TEST_H
#define NR_TEST_H
#pragma once

#include "Thing.h"

namespace MyApp
{
 // ...
}

#endif

इस तरह आपको दोनों (क्रॉस-प्लेटफ़ॉर्म और मदद संकलन गति) का सबसे अच्छा मिलता है।

जैसा कि यह टाइप करने के लिए लंबा है, मैं व्यक्तिगत रूप से एक बहुत ही विकी तरीके से (विजुअल असिस्ट एक्स) उत्पन्न करने में मदद करने के लिए एक उपकरण का उपयोग करता हूं।


क्या Visual Studio #include गार्ड को इस प्रकार नहीं अनुकूलित करता है? अन्य (बेहतर?) संकलक ऐसा करते हैं, और मुझे लगता है कि यह काफी आसान है।
टॉम

1
तुम क्यों रखूँ pragmaके बाद ifndef? क्या कोई लाभ है?
user1095108

1
@ user1095108 कुछ कंपाइलर हेडर गार्ड का उपयोग यह जानने के लिए सीमांकक के रूप में करेंगे कि क्या फाइल में केवल कोड है जिसे एक बार इंस्टेंट करना है। यदि हेडर गार्ड के बाहर कुछ कोड है, तो पूरी फाइल को एक से अधिक बार शायद तत्काल माना जा सकता है। यदि वही कंपाइलर एक बार प्रज्ञा का समर्थन नहीं करता है, तो यह उस निर्देश की अनदेखी करेगा। इसलिए, हेडर गार्ड के अंदर एक बार प्रज्ञा को डालना यह सुनिश्चित करने का सबसे सामान्य तरीका है कि कम से कम हेडर गार्ड को "अनुकूलित" किया जा सकता है।
Klaim

4

हर बार नहीं।

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52566 दोनों को शामिल करने के लिए दो फ़ाइलों का एक अच्छा उदाहरण है, लेकिन गलती से समान टाइमस्टैम्प और सामग्री (समान फ़ाइल नाम नहीं) के कारण समान माना जाता है ।


10
यह संकलक में एक बग होगा। (शॉर्टकट लेने की कोशिश नहीं करनी चाहिए)।
rxantos

4
#pragma onceगैर-मानक है, इसलिए जो कुछ भी संकलक करने का निर्णय करता है वह "सही" है। बेशक, फिर हम इस बारे में बात करना शुरू कर सकते हैं कि "अपेक्षित" क्या है और "उपयोगी" क्या है।
user7610

2

बहुत बड़े पेड़ों पर gcc 3.4 और 4.1 का उपयोग करना (कभी-कभी distcc का उपयोग करना ) ), मुझे अभी तक किसी भी गति को देखने के लिए है जब #pragma के बदले में एक बार उपयोग किया जाता है, या मानक के साथ संयोजन में गार्ड शामिल होते हैं।

मैं वास्तव में नहीं देखता कि कैसे इसके संभावित रूप से gcc के पुराने संस्करणों को भ्रमित कर रहा है, या यहां तक ​​कि अन्य संकलक भी हैं क्योंकि कोई वास्तविक बचत नहीं है। मैंने विभिन्न डी-लिंटर के सभी प्रयास नहीं किए हैं, लेकिन मैं शर्त लगाने को तैयार हूं कि यह उनमें से कई को भ्रमित करेगा।

मैं भी चाहता हूं कि इसे जल्दी अपनाया जाए, लेकिन मैं इस तर्क को देख सकता हूं कि "हमें उस समय की आवश्यकता क्यों है, जब ifndef पूरी तरह से ठीक है?"। सी के कई अंधेरे कोनों और जटिलताओं को देखते हुए, गार्ड शामिल हैं सबसे आसान, स्वयं को समझाने वाली चीजों में से एक है। यदि आपके पास एक छोटा सा भी ज्ञान है कि प्रीप्रोसेसर कैसे काम करता है, तो उन्हें आत्म व्याख्यात्मक होना चाहिए।

यदि आप एक महत्वपूर्ण गति का निरीक्षण करते हैं, तो कृपया अपना प्रश्न अपडेट करें।


2

आज पुराने स्कूल में शामिल गार्ड एक बार के रूप में उपवास के रूप में एक बार कर रहे हैं। यहां तक ​​कि अगर कंपाइलर उन्हें विशेष रूप से व्यवहार नहीं करता है, तो यह तब भी बंद हो जाएगा जब यह देखता है कि #ifndef WHATEVER और WHATEVER परिभाषित है। फ़ाइल खोलना आज गंदगी सस्ती है। यहां तक ​​कि अगर कोई सुधार होना था, तो यह मिलिसकंड के क्रम में होगा।

मैं बस #pragma का एक बार उपयोग नहीं करता, क्योंकि इसका कोई लाभ नहीं है। अन्य लोगों के साथ टकराव से बचने के लिए मैं कुछ का उपयोग करता हूं जैसे: CI_APP_MODULE_FILE_H -> CI = कंपनी की शुरुआत; एपीपी = आवेदन नाम; बाकी स्व-व्याख्यात्मक है।


19
क्या यह लाभ नहीं है कि यह बहुत कम टाइपिंग है?
एंड्रे

1
ध्यान दें कि कुछ मिलीसेकंड सौ हजार बार कुछ मिनट होते हैं, हालांकि। बड़ी परियोजनाओं में दस हजार फाइलें शामिल हैं जिनमें दसियों हेडर शामिल हैं। वर्तमान में कई कोर सीपीयू, इनपुट / आउटपुट को देखते हुए, विशेष रूप से कई छोटी फाइलें खोलने में, प्रमुख अड़चनों में से एक है।
डेमोन

1
"आज ओल्ड-स्कूल में गार्ड शामिल हैं, जितनी तेजी से एक बार # प्रताप आया।" आज, और कई साल पहले भी। GCC साइट पर सबसे पुराने डॉक्स २००१ के २.९ ​​५ के लिए हैं और इसमें शामिल गार्डों का अनुकूलन करना तब नया नहीं था। यह एक हालिया अनुकूलन नहीं है।
जोनाथन वेकली

4
मुख्य लाभ यह है कि गार्ड में त्रुटि-प्रवण और वर्डी शामिल हैं। अलग-अलग निर्देशिकाओं में समान नामों के साथ दो अलग-अलग फ़ाइलों को रखना बहुत आसान है (और गार्ड्स समान प्रतीक हो सकते हैं), या कॉपी-पेस्ट त्रुटियों को शामिल करते हुए कॉपी करना शामिल करें। एक बार प्रज्ञा कम त्रुटि-ग्रस्त है, और सभी प्रमुख पीसी प्लेटफार्मों पर काम करती है। यदि आप इसका उपयोग कर सकते हैं, तो यह बेहतर शैली है।
हेल्प्स

2

मुख्य अंतर यह है कि संकलक को शामिल गार्ड को पढ़ने के लिए हेडर फ़ाइल खोलनी थी। इसकी तुलना में, प्राग्मा एक बार कंपाइलर को फ़ाइल का ट्रैक रखने और किसी भी फाइल IO को न करने का कारण बनता है जब वह उसी फ़ाइल के लिए किसी अन्य में आता है। हालांकि यह नगण्य लग सकता है, यह बड़ी परियोजनाओं के साथ आसानी से बढ़ सकता है, विशेष रूप से अच्छे हेडर वाले विषयों में शामिल हैं।

उस ने कहा, इन दिनों संकलक (जीसीसी सहित) व्यवहार करने के लिए पर्याप्त स्मार्ट हैं, जिसमें एक बार प्रज्ञा जैसे गार्ड शामिल हैं। यानी वे फ़ाइल नहीं खोलते हैं और फ़ाइल IO पेनल्टी से बचते हैं।

कंपाइलरों में जो न तो प्रज्ञा का समर्थन करते हैं, मैंने मैनुअल कार्यान्वयन को देखा है जो थोड़ा बोझिल हैं।

#ifdef FOO_H
#include "foo.h"
#endif

मैं व्यक्तिगत रूप से #pragma को पसंद करता हूं, क्योंकि यह नामकरण टकराव और संभावित टाइपो त्रुटियों की परेशानी से बचा जाता है। यह तुलना से भी अधिक सुंदर कोड है। कहा कि, पोर्टेबल कोड के लिए, यह दोनों को चोट नहीं पहुंचनी चाहिए जब तक कि कंपाइलर इसके बारे में शिकायत न करे।


1
"कहा कि, इन दिनों संकलक (जीसीसी सहित) व्यवहार करने के लिए पर्याप्त स्मार्ट हैं, जिसमें एक बार प्रज्ञा जैसे गार्ड शामिल हैं।" वे दशकों से कर रहे थे, शायद अब तक #pragma onceअस्तित्व में है!
जोनाथन वेकली

सोचिए आपने मुझे गलत समझा। मैं एक बार प्राग्मा से पहले कहने का मतलब था, सभी कंपाइलर एक ही एच फ़ाइल के लिए कई आईओ पेनिटीज़ को उकसाएंगे जिसमें प्रीप्रोसेसर स्टेज के दौरान कई बार शामिल थे। आधुनिक कार्यान्वयन प्रीप्रोसेसर चरण में फ़ाइलों के बेहतर कैशिंग का उपयोग करके समाप्त होते हैं। भले ही, प्रैग्मस के बिना, प्रीप्रोसेसर मंच अभी भी शामिल गार्ड के बाहर सब कुछ सहित समाप्त होता है। एक बार प्रज्ञा के साथ, पूरी फ़ाइल को छोड़ दिया जाता है। उस दृष्टिकोण से, अभी भी लाभप्रद है।
शम्मी

1
नहीं, यह गलत है, सभ्य संकलक पूरी फाइल को एक बार भी #pragma के बिना छोड़ देते हैं, वे दूसरी बार फाइल नहीं खोलते हैं और वे दूसरी बार भी इसे नहीं देखते हैं, gcc.gnu.org/onbuildocs/ देखें cpp / Once-Only-Headers.html (यह कैशिंग से कोई लेना-देना नहीं है)।
जोनाथन वेकली

1
आपके लिंक से, ऐसा लगता है कि अनुकूलन केवल cpp में होता है। बावजूद, कैशिंग खेलने में आता है। प्रीप्रोसेसर को गार्ड के बाहर कोड शामिल करना कैसे पता होता है। उदाहरण ... बाहरी int foo; #ifndef INC_GUARD #define INC_GUARD वर्ग ClassInHeader {}; #endif इस मामले में प्रीप्रोसेसर को बाहरी int foo को शामिल करना होगा; यदि आप एक ही फ़ाइल को कई बार शामिल करते हैं तो कई बार। दिन का अंत, जब तक हम #pragma के बीच के अंतर को समझ नहीं लेते हैं, तब तक इस पर बहुत अधिक बहस नहीं करते हैं और गार्ड शामिल करते हैं और विभिन्न कंपाइलर दोनों के साथ कैसा व्यवहार करते हैं :)
Shammi

1
यह उस में अनुकूलन लागू नहीं करता है, जाहिर है।
जोनाथन वैक्ली

1

यदि हम Gvc (Qt 4.5 तक) का उपयोग करते हैं, तो GCC (3.4 तक), msvc दोनों का समर्थन करते हैं #pragma once, मैं उपयोग न करने का कोई कारण नहीं देख सकता #pragma once

स्रोत फ़ाइल का नाम आमतौर पर समान वर्ग नाम होता है, और हम जानते हैं, कभी-कभी हमें नाम बदलने के लिए, कक्षा के नाम को बदलने की आवश्यकता होती है , तो हमें #include XXXXभी बदलना होगा , इसलिए मुझे लगता है कि मैनुअल बनाए रखना #include xxxxxएक स्मार्ट काम नहीं है। विजुअल असिस्ट एक्स एक्सटेंशन के साथ भी, "xxxx" बनाए रखना आवश्यक काम नहीं है।


1

लोगों के लिए अतिरिक्त नोट यह सोचकर कि हेडर फ़ाइलों का एक बार-केवल-समावेश हमेशा वांछित है: मैं दशकों से हेडर फ़ाइलों के दोहरे या एकाधिक समावेश का उपयोग करके कोड जनरेटर का निर्माण करता हूं। विशेष रूप से प्रोटोकॉल लाइब्रेरी स्टब्स की पीढ़ी के लिए मुझे कोई अतिरिक्त उपकरण और भाषाओं के साथ एक अत्यंत पोर्टेबल और शक्तिशाली कोड जनरेटर होना बहुत आरामदायक लगता है। मैं इस योजना को एक्स-मैक्रोज़ शो के रूप में इस योजना का उपयोग करने वाला एकमात्र डेवलपर नहीं हूं । यह लापता स्वचालित रखवाली के बिना करना संभव नहीं होगा।


क्या C ++ टेम्पलेट समस्या का समाधान कर सकता है? मुझे शायद ही कभी मैक्रो के लिए कोई वैध आवश्यकता मिलती है क्योंकि C ++ टेम्प्लेट कैसे।
क्लियर

1
हमारा दीर्घकालिक पेशेवर अनुभव यह है कि हर समय परिपक्व भाषा, सॉफ्टवेयर और उपकरण के बुनियादी ढांचे का उपयोग करने से हमें सेवा प्रदाता (एंबेडेड सिस्टम) के रूप में उत्पादकता और लचीलेपन में भारी लाभ मिलता है। C ++ आधारित एम्बेडेड सिस्टम सॉफ़्टवेयर और स्टैक विकसित करने वाले प्रतियोगी इसके बजाय अपने कुछ डेवलपर्स को काम में अधिक खुश पा सकते हैं। लेकिन हम आम तौर पर उन्हें कई बार बाजार, कार्यक्षमता और लचीलेपन से बेहतर प्रदर्शन करते हैं। एक और बार-बार एक ही उपकरण का उपयोग करने से नीदरलैंड को कम उत्पादकता का लाभ मिलता है। इसके बजाय वेब-देवता कई फ्रेमवर्क के तरीकों से पीड़ित हैं।
मार्सेल

एक नोट हालांकि: DRY सिद्धांत के खिलाफ हर हेडर फ़ाइल में एक बार गार्ड / # प्रागमा शामिल नहीं है। मैं आपकी बात को X-Macroफीचर में देख सकता हूं , लेकिन यह शामिल करने का मुख्य उपयोग नहीं है, क्या यह हेडर अनगार्ड / # प्रैगमा मल्टी जैसे अन्य तरीके से नहीं होना चाहिए यदि हम DRY के साथ रहना चाहते हैं?
caiohamamura

DRY का अर्थ है "अपने आप को दोहराना मत"। इसके बारे में मानव मशीन क्या कर रही है, इसका उस प्रतिमान से कोई लेना-देना नहीं है। C ++ टेम्प्लेट बहुत दोहराते हैं, C- कंपाइलर ऐसा ही करते हैं (जैसे लूप अन्रॉलिंग) और हर कंप्यूटर लगभग हर चीज को अक्सर और तेजी से दोहरा रहा है।
मार्सेल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.