क्या Cpr 11 मानक का एक बार #pragma हिस्सा है?


140

परंपरागत रूप से, C ++ में कई हेडर इंक्लूज़न से बचने के लिए मानक और पोर्टेबल तरीका #ifndef - #define - #endifप्री-कंपाइलर डायरेक्टिव स्कीम का उपयोग करना है जिसे मैक्रो-गार्ड स्कीम भी कहा जाता है (नीचे कोड स्निपेट देखें)।

#ifndef MY_HEADER_HPP
#define MY_HEADER_HPP
...
#endif

हालांकि अधिकांश कार्यान्वयन / संकलक (नीचे चित्र देखें) में, अधिक "सुरुचिपूर्ण" विकल्प है जो मैक्रो-गार्ड योजना के समान उद्देश्य को पूरा करता है #pragma once#pragma onceमैक्रो-गार्ड स्कीम की तुलना में कई फायदे हैं, जिनमें कम कोड, नाम की गड़बड़ी से बचना और कभी-कभी बेहतर संकलन गति शामिल है।

यहां छवि विवरण दर्ज करें

कुछ शोध करते हुए, मैंने महसूस किया कि यद्यपि #pragma onceनिर्देश लगभग सभी ज्ञात संकलकों द्वारा समर्थित है, फिर भी इस बात पर अशांति है कि क्या #pragma onceनिर्देश C ++ 11 मानक का हिस्सा है या नहीं।

प्रशन:

  • क्या कोई स्पष्ट कर सकता है कि #pragma onceनिर्देश सी ++ 11 मानक का हिस्सा है या नहीं?
  • यदि यह C ++ 11 मानक का हिस्सा नहीं है, तो क्या बाद की रिलीज़ (जैसे, C ++ 14 या बाद के संस्करण) पर इसे शामिल करने की कोई योजना है?
  • यह भी अच्छा होगा यदि कोई किसी एक तकनीक (यानी, मैक्रो-गार्ड एसे #pragma once) का उपयोग करके फायदे / नुकसान के बारे में विस्तार से बता सके ।

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

9
कैपिटल लेटर के बाद एक प्रमुख अंडरस्कोर का उपयोग करना भी वर्जित है। दूसरा, अशांति कहाँ है? मैं बस संकलक समर्थन देख रहा हूं, मैं यह दावा करता हूं कि यह मानक का हिस्सा है?
यक्क - एडम नेवरामोंट

1
तीसरे बुलेटपॉइंट के लिए संबंधित प्रश्न देखें: क्या #pragma एक बार एक सुरक्षित गार्ड में शामिल है? यह एक ऐसी स्थिति है जहां हेडर गार्ड काम करते हैं लेकिन #pragma onceआमतौर पर ऐसा नहीं होता है।
user1942027

1
उस में संभव डुप्लिकेट यह C ++ 11 का उल्लेख किए बिना इस प्रश्न का उत्तर देता है।
यक्क - एडम नेवरामोंट १६'१४

3
ठीक है, यह किसी भी आधिकारिक दस्तावेज़ में कोडित नहीं है, लेकिन आप इसे वास्तविक मानक के रूप में मान सकते हैं ।
सियान रेन

जवाबों:


107

#pragma onceहै मानक। यह एक व्यापक (लेकिन सार्वभौमिक नहीं) विस्तार है, जिसका उपयोग किया जा सकता है

  • यदि आपकी पोर्टेबिलिटी चिंताएं सीमित हैं, और
  • आप यह सुनिश्चित कर सकते हैं कि आपकी सभी शामिल फाइलें हमेशा एक स्थानीय डिस्क पर हों।

इसे मानकीकरण के लिए माना गया था, लेकिन इसे अस्वीकार कर दिया गया क्योंकि इसे मज़बूती से लागू नहीं किया जा सकता है। (समस्याएँ तब होती हैं जब आपके पास कई अलग-अलग दूरस्थ mounts के माध्यम से फ़ाइलें सुलभ होती हैं।)

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


11
सिर्फ रिमोट माउंट नहीं। हार्डलिंक, सॉफ्टलिंक, विकल्प निर्माण (विंडोज पर)। यह वास्तव में गड़बड़ हो सकता है।
टॉनी

45
फ़ाइलों की पहचान करने के लिए कंपाइलर SHA-1 या MD5 चेकसम का उपयोग क्यों नहीं कर सकता है?
सर्जेई

29
मैं वास्तव में मानक में कुछ नहीं डालने की बात नहीं देखता अगर हर प्रमुख संकलक इसका समर्थन करता है। वास्तव में मानक से बहुत कम समर्थित चीजें हैं। इसके अलावा, एज मुद्दों के बारे में शिकायत करने के लिए यह बहुत ही मूर्खतापूर्ण लगता है, जब हम फ़ाइलों को शामिल करने के बारे में बात कर रहे हैं, जहां फ़ाइलनाम क्लैश पहले से ही एक बड़ा मुद्दा है। यह अच्छा होता अगर सामान्य रूप से #included हैडर फ़ाइलों की अवधारणा पर 100% अंक-मुक्त सुविधा की मांग को लागू किया गया होता।
TED

38
यदि आपके कोड में प्रतीकात्मक लिंक या अजीब mounts के माध्यम से विभिन्न स्थानों से कुछ फ़ाइल शामिल है, तो यह पहले से ही पोर्टेबल नहीं है। इसलिए यह तर्क देना कि pragma onceकुछ ऐसा नहीं है जो स्वाभाविक रूप से लागू नहीं कर सकता है जो स्वाभाविक रूप से पोर्टेबल नहीं है (और इस पर भी विचार नहीं किया जाना चाहिए) अभी तक C ++ दुनिया का एक और बकवास है।
doc

7
@JoseAntonioDuraOlmos मैं सहमत हूं कि प्रतीकात्मक लिंक एक OS सुविधा है, जो C ++ भाषा के दायरे से बाहर है। इसलिए सवाल उठता है कि C ++ कॉमेटी को भाषा के दायरे से बाहर होने वाली किसी चीज़ पर विचार क्यों करना चाहिए? किसी ऐसी चीज़ की गारंटी देने की कोशिश करना जो उनकी ज़िम्मेदारी नहीं है, इसका कोई मतलब नहीं है। डॉस ने फ़ाइल नाम के अनुसार केवल 8 + 3 चार्ट का समर्थन किया है, फिर भी किसी ने तर्क नहीं दिया है कि #includeइसे हटाया जाना चाहिए, क्योंकि कोई भी निर्देश का गलत उपयोग कर सकता है। #pragma onceपोर्टेबिलिटी को किसी भी तरह से प्रतिबंधित नहीं करता है, बशर्ते कि आप संकलन को तोड़ने के लिए प्रतीकात्मक लिंक का शोषण नहीं करेंगे।
दस्तावेज़

32

मानक ( N3936 ड्राफ्ट) की धारा draft16.6 इस #pragmaप्रकार है:

प्रपत्र का एक पूर्वप्रक्रमक निर्देश

# pragma pp-tokensopt new-line

कार्यान्वयन-परिभाषित तरीके से व्यवहार करने के लिए कार्यान्वयन का कारण बनता है। व्यवहार में अनुवाद विफल हो सकता है या अनुवादक या परिणामस्वरूप कार्यक्रम को गैर-अनुरूप तरीके से व्यवहार करने का कारण हो सकता है। कार्यान्वयन द्वारा मान्यता प्राप्त किसी भी प्रज्ञा को अनदेखा नहीं किया जाता है।

मूल रूप #pragma onceसे एक #pragmaनिर्देश का एक कार्यान्वयन विशिष्ट उदाहरण है , और नहीं, यह मानक नहीं है। फिर भी।

यह अक्सर जीसीसी और क्लैंग सहित अधिकांश "प्रमुख संकलकों" द्वारा व्यापक रूप से समर्थित होता है और इसलिए कभी-कभी इसमें शामिल होने वाले बॉयलरप्लेट से बचने की सिफारिश की जाती है।


10
ध्यान दें कि आप #pragmaऔर #defineहेडर-गार्ड दोनों कर सकते हैं ।
यक्क - एडम नेवरुमोंट

18
"कार्यान्वयन से मान्यता प्राप्त कोई भी नजरअंदाज नहीं किया जाता है" । क्या इसका मतलब यह है कि संदेश: चेतावनी: गैर- मान्यताप्राप्त प्रज्ञा निर्देश गैर अनुरूप है?
रॉडरिगो

6
"और इसलिए शामिल-गार्ड बॉयलरप्लेट से बचने के लिए अनुशंसित तरीका है" - एक बहुत ही बोल्ड स्टेटमेंट। यह एक गैर-मानक तरीका है, और इसका उपयोग करने के लाभ कम हैं और मेरे अनुभव में शायद ही प्रासंगिक रहे हैं, इसलिए मुझे अपना +1 दूर ले जाना पड़ा।
एलेक्स

19
@Yakk: अगर कोई #defineहेडर-गार्ड लिखता है , तो उसके पास लिखने के लिए कोई कारण नहीं है #pragma once
नवाज़

5
@ नवाज़ एक कंपाइलर प्रत्येक फ़ाइल (पथ द्वारा) का एक कैश रख सकता है जो #pragma onced है, और इस घटना में कि वह #includeफिर से d है #include(फ़ाइल को भी नहीं खोल सकता है) को छोड़ सकता है । gcc हैडर गार्ड के साथ भी ऐसा ही करता है , लेकिन यह बहुत ही नाजुक है। #pragmaएक करने के लिए आसान है, हैडर गार्ड एक कठिन है।
यक्क - एडम नेवरुमोंट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.