2012-01-25 16 views
40

मैं कई सर्वोच्च हेडर फाइल में मैक्रो नीचे देखा है:क्या यह सुरक्षित है # Nfull nullptr?

#define NULL 0 // C++03 

कोड भर में, NULL और 0 दूसरे के स्थान पर किया जाता है। अगर मैं इसे बदलता हूं।

#define NULL nullptr // C++11 

यह किसी भी बुरा पक्ष प्रभाव का कारण बन जाएगा? मैं केवल (अच्छे) दुष्प्रभाव के बारे में सोच सकता हूं क्योंकि निम्नलिखित उपयोग खराब हो जाएगा;

int i = NULL; 

उत्तर

39

मैं सर्वोच्च हेडर फाइल में मैक्रो नीचे देखा है:

आपको लगता है कि देखा है नहीं करना चाहिए, मानक पुस्तकालय <cstddef> (और <stddef.h>) में यह परिभाषित करता है। और, आईआईआरसी, मानकों के मुताबिक मानक हेडर फाइलों द्वारा परिभाषित नामों को फिर से परिभाषित करने के परिणामस्वरूप अपरिभाषित व्यवहार होता है। तो पूरी तरह से मानक दृष्टिकोण से, आपको ऐसा नहीं करना चाहिए।


मैंने देखा है लोगों को निम्नलिखित, जो भी कारण के लिए कर के उनके टूटे मन सोचा:

struct X{ 
    virtual void f() = NULL; 
} 

(में [गलत तरीके से] के रूप में: "NULL करने के लिए आभासी तालिका सूचक सेट")

यह तभी मान्य NULL, क्योंकि = 0 शुद्ध आभासी कार्य (§9.2 [class.mem]) के लिए मान्य टोकन है 0 के रूप में परिभाषित किया जाता है।

जिसके अनुसार, अगर NULL था सही ढंग से एक अशक्त सूचक निरंतर रूप में इस्तेमाल किया है, तो कुछ भी नहीं तोड़ना चाहिए।

हालांकि, कि सावधान रहना, मालूम होता है सही ढंग से इस्तेमाल भले ही, इस बदल जाएगा:

void f(int){} 
void f(char*){} 

f(0); // calls f(int) 
f(nullptr); // calls f(char*) 

हालांकि, अगर है कि कभी मामला था, यह लगभग निश्चित रूप से वैसे भी टूट गया था।

+0

'आपको वह नहीं देखा जाना चाहिए था'। तुम ऐसा क्यों महसूस करते हो? मैंने डब्लूसीडीएमए एल 1 के लिए डीएसपी के उत्पादन कोड में '# डिफिन न्यूल (शून्य *) (0)' जैसे अजीब मैक्रो को भी देखा है। – iammilind

+6

'वर्चुअल शून्य एफ() = 0 एल;' कानूनी है? क्योंकि '# डिफिन न्यूल 0 एल' निश्चित रूप से एक अनुरूप कार्यान्वयन है। –

+6

@iammilind: आपको नहीं करना चाहिए, क्योंकि 'NULL' पहले ही मानक द्वारा परिभाषित किया गया है। – Xeo

14

सुदूर बेहतर खोज और कोड भर nullptr साथ NULL को बदलने के लिए है।

यह वाक्य रचनात्मक रूप से सुरक्षित हो सकता है, लेकिन आप #define कहां रखेंगे? यह कोड संगठन की समस्याएं पैदा करता है।

+10

'जी ++ -DNULL = nullptr ...' :) – Xeo

+7

मैं कोड जो कुछ की आवश्यकता पर विचार कंपाइलर झंडे गैर पोर्टेबल होने के लिए। – spraff

+0

खैर, मुझे लगता है कि हम -विंडोज़ या ऐसा कुछ भी नहीं कर सकते हैं, और हमें अपने सभी कोड ग्राउंड को फिर से लिखना होगा ताकि इसे किसी अन्य प्लेटफ़ॉर्म पर पोर्ट किया जा सके ... –

2

हालांकि यह पुरानी सामग्री के साथ पिछड़ा-संगतता तोड़ सकता है जो (या तो, या अत्यधिक चालाक ...), आपके नए कोड के लिए, यह एक गैर-मुद्दा है। आपको nullptr का उपयोग करना चाहिए, और NULL नहीं, जहां आपका मतलब nullptr है। साथ ही, आपको 0 का उपयोग करना चाहिए जहां आपका शून्य शून्य है।

+3

ध्यान रखें कि अच्छी तरह लिखित पुरानी सामग्री 'नलप्टर' का उपयोग नहीं करेगी, क्योंकि इसे कुछ महीने पहले ही भाषा में जोड़ा गया था। –

+1

@ माइक: अच्छी तरह से लिखित पुरानी सामग्री में '#define NULLPTR NULL' जैसी कुछ हो सकती है, हालांकि, जिसे C++ 11 के रूप में संकलित करते समय 'NDLPTR nullptr' को परिभाषित किया जा सकता है। और उसके बाद कोड में 'NULLPTR' के सभी उदाहरण हटा दिए जाने के बाद हटा दिया जाता है कि आपको कभी भी इसे C++ 03 के रूप में संकलित नहीं करना पड़ेगा। –

+1

@SteveJessop गंभीरता से? मेरा मतलब है, शायद अब हम नलप्टर के बारे में जानते हैं कि NULLPTR मैक्रो समझ में आएगा, लेकिन पुराना कोड (* पहले * नलप्टर मानक में जोड़ा गया था) ऐसा लगता है .. असंभव है। – luiscubal

4

आपको इसे बिल्कुल परिभाषित नहीं करना चाहिए, जब तक कि आप अपना खुद का संस्करण <cstddef> लिख रहे हों; यह निश्चित रूप से "कई शीर्ष शीर्षलेख फाइलों" में नहीं होना चाहिए।

आप अपने खुद के मानक पुस्तकालय को लागू कर रहे हैं, उसके बाद ही आवश्यकता

18,2/3 मैक्रो रिक्त है एक कार्यान्वयन से परिभाषित C++ है नल पॉइंटर निरंतर

तो या तो 0 या nullptr स्वीकार्य है, और nullptr आपके द्वारा दिए गए कारण के लिए बेहतर है (यदि आपका कंपाइलर इसका समर्थन करता है)।

7

नहीं। आपको मानक मैक्रोज़ को परिभाषित करने की अनुमति नहीं है। और अगर आप किसी भी एक मानक हेडर के अलावा अन्य फ़ाइल के शीर्ष पर

#define NULL 0 

देखते हैं (और यहां तक ​​कि वहाँ है, यह में होना चाहिए गार्ड शामिल हैं, और अतिरिक्त गार्ड में आम तौर पर साथ ही), तो उस फ़ाइल टूट गया है । इसे हटा दो।

ध्यान दें कि अच्छा compilers आम तौर पर कुछ की तरह साथ NULL परिभाषित करेगा: एक संकलक builtin अगर यह एक गैर सूचक संदर्भ में प्रयोग किया है जो एक चेतावनी ट्रिगर किया जाएगा तक पहुँचने के लिए

#define NULL __builtin_null 

,।

+0

शायद यही वजह है कि इसे फिर से परिभाषित किया गया था: चेतावनियों को दूर करने का आलसी तरीका ... –

4

शायद नहीं

आप अधिक भार व्यवहार की एक विशेष प्रारूप है:

void foo(int); 
void foo(char*); 

तो कोड के व्यवहार:

foo(NULL); 

चाहे शून्य है के आधार पर बदल जाएगा बदले में बदल गया या नहीं।

बेशक

, वहाँ के रूप में है कि क्या यह सुरक्षित है के रूप में इस सवाल का जवाब में मौजूद है इस तरह के कोड लिखने के लिए एक और सवाल है ...

संबंधित मुद्दे