C, C ++ का उपसमूह कहां नहीं है? [बन्द है]


116

मैंने बहुत सी किताबों में पढ़ा कि C, C ++ का सबसेट है।

कुछ पुस्तकों का कहना है कि C, छोटे विवरणों को छोड़कर , C ++ का सबसेट है ।

कुछ मामले क्या हैं जब कोड सी में संकलित होगा, लेकिन सी ++ नहीं?

जवाबों:


135

अगर आप तुलना C89करते हैं C++तो यहां कुछ बातें हैं

C ++ में कोई अस्थायी परिभाषा नहीं

int n;
int n; // ill-formed: n already defined

int [] और int [N] संगत नहीं (C ++ में कोई संगत प्रकार नहीं)

int a[1];
int (*ap)[] = &a; // ill-formed: a does not have type int[]

कोई K & R फ़ंक्शन परिभाषा शैली नहीं

int b(a) int a; { } // ill-formed: grammar error

नेस्टेड स्ट्रक्चर में C ++ में क्लास-स्कोप है

struct A { struct B { int a; } b; int c; };
struct B b; // ill-formed: b has incomplete type (*not* A::B)

कोई डिफ़ॉल्ट इंट नहीं

auto a; // ill-formed: type-specifier missing

C99 कई अन्य मामलों को जोड़ता है

मापदंडों के सरणी आयामों में घोषणा विनिर्देशकों की कोई विशेष हैंडलिंग नहीं

// ill-formed: invalid syntax
void f(int p[static 100]) { }

कोई चर लंबाई सरणियाँ

// ill-formed: n is not a constant expression
int n = 1;
int an[n];

कोई लचीला सरणी सदस्य नहीं है

// ill-formed: fam has incomplete type
struct A { int a; int fam[]; }; 

अलियासिंग विश्लेषण में मदद करने के लिए कोई योग्यताधारी नहीं

// ill-formed: two names for one parameter?
void copy(int *restrict src, int *restrict dst);

@ श्रीमद, धन्यवाद सी। फिक्स्ड में नेस्टेड संरचना की घोषणा करते समय ओओ को यह नहीं पता था कि पहले से ही एक वैरिएबल बनाना है।
जोहान्स स्काउब -

3
एक और (बेकार) C89 से C ++ एक है: C typedef;में एक कानूनी TU है, लेकिन C ++ में नहीं।
फ्लेक्सो

सूचना जो auto a;नवीनतम C ++ मानक संशोधन में मान्य है।
फ़ूज

3
@FUZxxl सच में? कटौती प्रकार क्या होगा a?
जोहान्स शहाब -

3
@FUZxxl आह धन्यवाद तो auto x;नवीनतम संशोधन में मान्य नहीं है, लेकिन उदाहरण के लिए auto x = 0;है। मैं पहले थोड़ा सा चौंक गया :)
जोहान्स शाउब -

50

सी में, sizeof('a')के बराबर है sizeof(int)

C ++ में, sizeof('a')के बराबर है sizeof(char)


46
यह करने के लिए simpified किया जा सकता है: सी में, 'a'एक है int। C ++ में, 'a'a char
पीजी

38

C ++ में नए कीवर्ड भी हैं। निम्नलिखित सी कोड मान्य है लेकिन C ++ के तहत संकलित नहीं किया जाएगा:

int class = 1;
int private = 2;
int public = 3;
int virtual = 4;

1
यह सच है, लेकिन वास्तव में यही सबसेट का मतलब है।
येयेरमैन

20
@yeyeyerman: नहीं। इसके लिए एक सबसेट होने के लिए, सभी C कोड को मान्य C ++ भी होना चाहिए। इस उदाहरण का कोड मान्य C है, लेकिन C ++ नहीं है।
:

24
नहीं, यदि C C ++ का एक सख्त उपसमूह था, तो प्रत्येक C प्रोग्राम एक मान्य C ++ प्रोग्राम होगा, लेकिन यह सच नहीं है। सवाल यह है कि यह सच क्यों नहीं है, और यह इसका एक उदाहरण है।
ग्रीम पेरो

हा! इस एक के बारे में नहीं सोचा था!
गेब रॉयर

20

बहुत सारी चीजें हैं। बस एक सरल उदाहरण (यह साबित करने के लिए पर्याप्त होना चाहिए कि C C ++ का उचित उपसमूह नहीं है):

int* test = malloc(100 * sizeof(int));

C में संकलित करना चाहिए लेकिन C ++ में नहीं।


3
C ++ को एक स्पष्ट कास्ट की आवश्यकता होनी चाहिए int*
मेहरदाद अफश्री

8
लंबे उत्तर: मॉलॉक रिटर्न void *, जो सी में किसी भी पॉइंटर प्रकार को सौंपा जा सकता है, और सी ++ को किसी अन्य पॉइंटर प्रकार को नहीं सौंपा जा सकता है।
डैनियल इयरविकर

5
इमेजिस्ट: एक सी संकलक, जैसा कि एएनएसआई C89 मानक द्वारा परिभाषित किया गया है, शिकायत नहीं करनी चाहिए।
मेहरदाद अफश्री

7
यह कानूनी है। कलाकार अनावश्यक है, गलत हो सकता है, और <stdlib.h> को शामिल करने में विफलता को कवर करता है। मैं मेहरदाद के कथन को सी। में लिखने का सही तरीका मानता हूं
डेविड थॉर्नले

16
@ आईमिस्ट: मैं आमतौर पर सी प्रोग्रामर से विपरीत सुनता हूं। वे कलाकारों को जोड़ने के लिए इसे खराब शैली मानते हैं, क्योंकि इससे कीड़े छिप सकते हैं। अच्छा C कोड कलाकारों का उपयोग नहीं करता है ।
जुल्फ

16

C ++ में, अगर आप की घोषणा एक struct, unionया enum, उसका नाम किसी भी क्वालिफायर के बिना तुरंत पहुँचा जा सकता है:

struct foo { ... };
foo x; // declare variable

सी में, यह काम नहीं करेगा, क्योंकि प्रकार इस प्रकार अपने अलग नामस्थान में लाइव घोषित किए जाते हैं। इस प्रकार, आपको लिखना होगा:

struct foo { ... };
struct foo x; // declare variable

structदूसरी पंक्ति पर वहां की उपस्थिति को ध्यान दें । आपको इसके लिए ( unionऔर enumउनके संबंधित खोजशब्दों का उपयोग करके), या typedefचाल का उपयोग करना होगा :

typedef struct { ... } foo;
foo x; // declare variable

नतीजतन, आपके पास C में एक ही नाम के कई प्रकार हो सकते हैं, क्योंकि आप नापसंद कर सकते हैं:

struct foo { ... };
typedef enum { ... } foo;

struct foo x;
foo y;

C ++ में, हालांकि, जब भी आप संदर्भ के structसाथ किसी नाम को उपसर्ग करते हैं, जब structभी आप इसे संदर्भित करते हैं, तो नाम स्थान विलीन हो जाते हैं, और इसलिए उपरोक्त C स्निपेट मान्य नहीं है। दूसरी ओर, C ++ विशेष रूप से एक प्रकार की अनुमति देने के लिए एक अपवाद बनाता है और उस प्रकार के लिए एक टाइपराइफ़ का एक ही नाम है (जाहिर है कोई प्रभाव नहीं), typedefसी से अपरिवर्तित चाल का उपयोग करने की अनुमति देने के लिए ।


1
आपकी आखिरी उदाहरण अमान्य C: तीन टैग ( struct, unionऔर enum) एक ही नाम स्थान को साझा करें। एक बेहतर उदाहरण होगाstruct foo { ... }; typedef enum { ... } foo;
schot

@ स्कोट: आप निश्चित रूप से सही हैं, सुधार के लिए धन्यवाद। अपडेट किया गया।
पावेल मिनेव

8

यह इस बात पर भी निर्भर करता है कि आप किस प्रकार की सी का उपयोग कर रहे हैं। स्ट्रॉस्ट्रुप ने C ++ को उतना ही संगत बनाया, जितना कि वह और कोई अधिक संगत नहीं था, 1989 एएनएसआई और 1990 आईएसओ मानकों के साथ, और 1995 के संस्करण ने कुछ भी नहीं बदला। सी समिति 1999 मानक के साथ कुछ अलग दिशा में चली गई, और सी ++ समिति ने अगले सी ++ मानक (संभवत: अगले वर्ष या तो) को कुछ बदलावों के अनुरूप बदलने के लिए बदल दिया है।

स्ट्रॉस्ट्रुप "द सी ++ प्रोग्रामिंग लैंग्वेज" के अपेंडिक्स B.2 में C90 / C95 के साथ असंगतताओं को सूचीबद्ध करता है, विशेष संस्करण (जो कुछ अतिरिक्त सामग्री के साथ तीसरा संस्करण है):

'a'एक है intसी में, एक charसी ++ में।

आकार एक Enum intC में है, जरूरी नहीं कि C ++ में हो।

C ++ में //लाइन के अंत में टिप्पणियां हैं, C (हालांकि यह एक सामान्य एक्सटेंशन नहीं है)।

सी ++ में, एक struct foo {परिभाषा fooवैश्विक नामस्थान में डालती है , जबकि सी में इसे के रूप में संदर्भित करना होगा struct foo। यह एक structपरिभाषा को एक बाहरी दायरे में नाम छाया करने की अनुमति देता है , और कुछ अन्य परिणाम हैं। इसके अलावा, C structपरिभाषाओं के लिए बड़ा स्कोप देता है , और उन्हें रिटर्न प्रकार और तर्क प्रकार की घोषणाओं की अनुमति देता है।

C ++ सामान्य प्रकार के बारे में उपद्रव है। यह एक पूर्णांक को एक को असाइन करने की अनुमति नहीं देगा enum, और void *वस्तुओं को एक कास्ट के बिना अन्य सूचक प्रकारों को नहीं सौंपा जा सकता है। सी में, एक ओवरलेग इनिशियलाइज़र प्रदान करना संभव है ( char name[5] = "David"जहां सी अनुगामी नल चरित्र को छोड़ देगा)।

C89 intकई संदर्भों में निहित है, और C ++ नहीं करता है। इसका मतलब यह है कि सभी कार्यों को C ++ में घोषित किया जाना चाहिए, जबकि C89 intमें फ़ंक्शन घोषणा में लागू सभी चीजों के लिए ग्रहण करने के साथ अक्सर यह संभव था ।

सी में, एक लेबल स्टेटमेंट का उपयोग करके ब्लॉक के बाहर से अंदर कूदना संभव है। C ++ में, यह अनुमति नहीं है अगर यह एक आरंभ को छोड़ देता है।

बाहरी लिंकेज में C अधिक उदार है। सी में, एक वैश्विक constचर स्पष्ट रूप से है extern, और यह सी ++ में सच नहीं है। C एक वैश्विक डेटा ऑब्जेक्ट को कई बार बिना घोषित किए जाने की अनुमति देता है extern, लेकिन यह C ++ में सही नहीं है।

कई सी ++ कीवर्ड सी में कीवर्ड नहीं हैं, या #defineमानक सी हेडर में घ हैं।

C की कुछ पुरानी विशेषताएं भी हैं जिन्हें अच्छी शैली नहीं माना जाता है। सी में, आप तर्कों की सूची के बाद तर्क परिभाषाओं के साथ एक फ़ंक्शन की घोषणा कर सकते हैं। सी में, एक घोषणा की तरह int foo()इसका मतलब है कि foo()किसी भी प्रकार के किसी भी तर्क ले सकते हैं, जबकि सी ++ में यह इसके बराबर है int foo(void)

यह स्ट्रॉस्ट्रुप से सब कुछ कवर करने के लिए लगता है।


आइए इस तथ्य को नहीं भूलना चाहिए कि, सी में, आपको एक गुंजाइश की शुरुआत में चर की घोषणा करनी चाहिए (यानी, तुरंत एक ब्रेस के बाद), जबकि, सी ++ कहीं भी चर घोषणाओं की अनुमति देता है।
रॉब जूल

4
हालाँकि, ऐसा कुछ C ++ कर सकता है जो C नहीं कर सकता। मुझे लगता है कि हम उन चीजों को देख रहे हैं जो आप C में कर सकते हैं लेकिन C ++ में नहीं।
डेविड थॉर्नले

2
@ रोब: यह C89 के लिए सही है लेकिन C99 के लिए नहीं।
jamesdlin

6

यदि आप जीसीसी का उपयोग करते हैं, तो -Wc++-compatआप सी कोड के बारे में चेतावनी देने के लिए चेतावनी का उपयोग कर सकते हैं जो किसी तरह से सी ++ में संदिग्ध है। इसका वर्तमान में gcc में ही उपयोग किया जाता है, और हाल ही में इसका उपयोग बहुत बेहतर हुआ है (हो सकता है कि आप जो सबसे अच्छा कर सकें उसके लिए एक रात्रि संस्करण का प्रयास करें)।

(यह सवाल का सख्ती से जवाब नहीं देता है, लेकिन लोक इसे पसंद कर सकता है)।


1
मैंने सोचा था कि मैं एक गैर-उत्तर उत्तर को आगे नहीं
बढ़ाऊंगा

4

मुझे लगता है कि सबसे बड़ा अंतर यह है कि यह एक वैध सी स्रोत फ़ाइल है:

int main()
{
    foo();
}

ध्यान दें कि मैंने fooकहीं भी घोषित नहीं किया है।

भाषा के अंतर के अलावा, C ++ पुस्तकालय में कुछ बदलाव भी करता है जो इसे C से विरासत में मिला है, जैसे कुछ कार्य const char *इसके बजाय वापस आते हैं char *


सी में प्रोटोटाइप की आवश्यकता नहीं है, लेकिन आमतौर पर उनका उपयोग न करने के लिए इसे बुरा अभ्यास माना जाता है।
रॉबर्ट गैम्बल

1
आपको s,C,C89,यह नोट करना चाहिए कि यह एक अमान्य C99 स्रोत फ़ाइल है।
जोहान्स शहाब -

क्या यह अमान्य है या अभी C99 में अपदस्थ है?
:

2
@ Jalf C99 ड्राफ्ट को C89 के लिए दस्तावेज़ों में शामिल करता है, और इसमें "हटाए गए int int" और "हटाए गए फ़ंक्शन की घोषणा" दोनों शामिल हैं।
जोहान्स स्काउब - १ 29:०२ पर


2

यहाँ कई जवाबों में सिंटेक्स अंतर होता है जो C89 (या C99) स्रोत कोड पर C ++ कंपाइलरों को विफल कर देगा। हालाँकि, कुछ सूक्ष्म भाषा अंतर हैं जो दोनों भाषाओं में कानूनी हैं लेकिन यह अलग व्यवहार का उत्पादन करेंगे। sizeof (char)अंतर यह है कि नवीन उल्लेख एक उदाहरण है, लेकिन एक प्रोग्राम है जो प्रिंट होगा 'सी' अगर एक (एएनएसआई) सी कार्यक्रम के रूप में संकलित है, और "सी ++" अगर एक सी ++ प्रोग्राम के रूप में संकलित लिखें कुछ अन्य लोगों सूचियों।


-2

C कंपाइलर्स आमतौर पर एक छोटे से कोने को काटने की अनुमति देते हैं जो C ++ नहीं करता है। C ++, C. की तुलना में बहुत अधिक सख्त है और आम तौर पर, इनमें से कुछ अंतर कंपाइलर-निर्भर होते हैं। उदाहरण के लिए g ++ कुछ चीजें अनुमति देता है जो Intel C ++ कंपाइलर नहीं करता है। यहां तक ​​कि काफी अच्छी तरह से लिखा सी कोड एक आधुनिक सी ++ संकलक के साथ संकलन नहीं करेगा।


-2

आप केवल सिंटैक्स द्वारा भाषाओं की तुलना नहीं कर सकते। यदि आप ऐसा करते हैं तो शायद आप C को C ++ के सबसेट के रूप में देख सकते हैं। मेरी राय में यह तथ्य है कि C ++ OO है (और C नहीं है) यह कहने के लिए पर्याप्त है कि C और C ++ अलग-अलग भाषाएँ हैं।


2
गलत। C ++ केवल OO नहीं है । आप सोच सकते हैं कि C ++ "C ++ = C + OO + जेनेरिक प्रोग्रामिंग + बोनस" जैसा है। इसे दूसरे तरीके से रखने के लिए, "C & C ++ ~ = C" जहां ~ = का अर्थ लगभग बराबर है।
पियरसेबल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.