2015-04-02 6 views
48

निम्न कोड जीसीसी के सभी संस्करणों पर बाद में संकलन त्रुटि उत्पन्न करता है जो मैंने कोशिश की है, सी ++ 98, सी ++ 11 और सी ++ 14 मोड में:त्रुटि: एनाक्रोनिस्टिक पुरानी शैली बेस क्लास प्रारंभकर्ता

struct T 
{ 
    T(void* x) : (x) {} 
}; 

// main.cpp: In constructor 'T::T(void*)': 
// main.cpp:3:18: error: anachronistic old-style base class initializer [-fpermissive] 
//  T(void* x) : (x) {} 
//     ^
// main.cpp:3:16: error: unnamed initializer for 'T', which has no base classes 
//  T(void* x) : (x) {} 

निश्चित रूप से, यह स्पष्ट रूप से टूटा हुआ कोड है क्योंकि मैं वास्तव में कुछ भी शुरू नहीं कर रहा हूं।

लेकिन यह बेस-क्लास प्रारंभिक क्यों है और यह गलत होने की बजाय "अनाचारवादी" क्यों है? क्या यह एक बार मान्य था? कब? और इसका क्या मतलब था?


only related references मैं वेब पर यह करने के लिए मिल गया है है लोगों से किया गया त्रुटि भर में आ रहा है जब एक सदस्य का नाम गलती से बाहर macro'd किया गया था, को प्रभावी ढंग से उपर दिए गए कोड में जिसके परिणामस्वरूप:

#define bar 
//^some library could have done this 

struct T 
{ 
    T(int x) 
     : bar(x) // effectively just `: (x)` 
    {} 

    int bar;  // will cause its own error 
}; 

उन लोगों को कभी पता नहीं चला कि त्रुटि क्या है, हालांकि बाद में कम से कम पता चला कि उनका कार्यक्रम क्यों टूट गया था।

+3

मैं _guess_ होगा कि यह वाक्यविन्यास क्लास के साथ सी में बेस क्लास प्रारंभिक वाक्यविन्यास था, सबसे पहले [गैर मानक] सी ++ ने कई विरासत पेश किए थे। –

+0

यह भी मेरे लिए सबसे व्यावहारिक परिकल्पना की तरह लगता है। दुर्भाग्यवश, मैं, आम, सामान्य चैनलों के माध्यम से "द सी ++ प्रोग्रामिंग भाषा" का पहला या दूसरा संस्करण नहीं ढूंढ पाया। मुझे यकीन है कि एसओ पर किसी के पास एक है, हालांकि। – Brian

+3

शायद "एनोटेटेड रेफरेंस मैनुअल" (एआरएम) की तलाश करें? –

उत्तर

51

CFront की 1984-5 जारी करने के लिए दस्तावेज में पाया जाता है, पहले सी ++ संकलक:

The constructor can be written like this:

vec.vec(int lb, int hb) : (hb-lb+1) 
    { 
     if (hb-lb<0) hb * lb 
     low = lb; 
     high = hb; 
    } 

The construct : (hb-lb+1) is used to specify the argument list needed for the base class constructor vector().

, भावना बनाता है अगर आप इसके बारे में सोचते हैं। संभावित रूप से बेस क्लास का स्पष्ट नामकरण एकाधिक विरासत का समर्थन करने के लिए जोड़ा गया था।

दस्तावेजों को संग्रहीत करने के लिए http://www.softwarepreservation.org/projects/c_plus_plus/ पर क्रेडिट।

... और वाह, मैं अभी अभी महसूस किया है कि "CFront" शब्दों पर एक नाटक था।

+3

.... अच्छा खोज। – Columbo

+0

हमारे बीच एक आदर्श बीमारी है। :) "सी ++ 2.0" ने कई विरासत समर्थन के लिए 1 9 8 9 में इसे बदल दिया। –

+6

भी मुझे भी woah –

22

वास्तव में यह मान्य मानक सी ++ नहीं है, इसलिए हमें उस बिंदु को खोजने के लिए भाषा के इतिहास के इतिहास को देखना चाहिए, जिस पर यह अमान्य हो गया था।

1989 में, जब आगे "सी ++" 1985 में उस नाम के तहत अपने मूल स्थापना के बाद से परिभाषित करने, Stroustrup घोषित एकाधिक वंशानुक्रम के साथ सामना करने के लिए है कि आधार initialisation, भाषा के पिछले अवतारों से बदल गया था: [1]

[p191] The C++ Programming Language [Stroustrup 1986] describes C++ as defined and implemented in August 1985. This paper describes the growth of the language since then and clarifies a few points in the definition. It is emphasized that these language modifications are extensions; C++ has been and will remain a stable language suitable for long term software development. The main new features of C++ are: multiple inheritance, type-safe linkage, better resolution of overloaded functions, recursive definition of assignment and initialization, better facilities for user-defined memory management, abstract classes, static member functions, const member functions, protected members, overloading of operator -> , and pointers to members. These features are provided in the 2.0 release of C++.

[p214]The syntax for initializing base classes and members has been extended to cope with multiple inheritance and the order of initialization has been more precisely defined. [..]

पाठ बेस-क्लास प्रारंभिक वाक्यविन्यास का प्रदर्शन करने के लिए चला जाता है जिसके साथ हम वर्तमान में परिचित हैं और, जैसा कि स्नीफ्टेल पहले से ही इंगित कर चुका है (मुझे किसी भी पुराने दस्तावेज के माध्यम से शिकार की परेशानी बचा रहा है!), यह नहीं था 1 9 85 के अंत में, मूल सी ++ कार्यान्वयन में जो स्वयं "कक्षाओं के साथ सी" से विकसित हुआ था। इसलिए, हम निष्कर्ष निकाल सकते हैं कि सी ++ 2.0 ने 1 9 8 9 में अधिक परिचित वाक्यविन्यास पेश किया और तब तक यह "एनाक्रोनिस्टिक" संस्करण मान्य था।

नोट, ज़ाहिर है कि प्रश्न के कोड में, कोई आधार नहीं है। तो, यहां तक ​​कि सी ++ 1.0 में, कार्यक्रम अंततः सफलतापूर्वक संकलित नहीं किया जाएगा। हालांकि, हमने पाया है कि सिंटैक्स को इस तरह से क्यों पार्स किया जा रहा है।

यह उल्लेखनीय है कि जीसीसी अस्पष्ट, लंबे समय से भुलाए गए वाक्यविन्यास का निदान कर रहा है जो लगभग तीस वर्षों तक सी ++ के किसी भी अवतार में मान्य नहीं है।


[1] "सी के विकास ++: 1985 करने के लिए 1989", Bjarne Stroustrup, एटी & टी बेल लेबोरेटरीज 1989; pdf

5

यह विशेष रूप से एआरएम, खंड 18.3.2 को एक अनाचारवाद के रूप में वर्णित किया गया था।

ऐसी विशेषताओं का कारण आमतौर पर सी ++ के पुराने संस्करणों या कक्षाओं के साथ सी को निरंतरता प्रदान करना था। सभी "anachronisms" अवांछित विशेषताओं था। कंपाइलर्स को ऐसी सुविधाएं प्रदान करने की आवश्यकता नहीं थी, लेकिन यदि उन्होंने किया, तो प्रोग्रामर को इसे निष्क्रिय करने और/या इसका उपयोग करने के बारे में चेतावनी देने की अनुमति देने के लिए बाध्य किया गया था।

+1

क्या आपके पास दावा के लिए कोई समर्थन है 'ए (int x) के बराबर: m (x) {} 'पहले उदाहरण में? – Sjoerd

+1

@Sjoerd मुझे नहीं लगता कि कोई है। सी ++ का संस्करण जिसमें बेस क्लास नाम प्रारंभकर्ता सिंटैक्स का हिस्सा नहीं था, ने कक्षाओं को ऐसे सदस्यों के लिए अनुमति नहीं दी जो डिफ़ॉल्ट-रचनात्मक नहीं थे। – Sneftel