c++ - tutorial - क्या प्रत्येक भाषा में संकलित होने पर कोड और सी++ दोनों में मान्य कोड अलग-अलग व्यवहार उत्पन्न कर सकता है?




द सी और प्रोग्रामिंग लैंग्वेज (11)

एक और sizeof जाल: बुलियन अभिव्यक्तियां।

#include <stdio.h>
int main() {
    printf("%d\n", (int)sizeof !0);
}

यह सी में sizeof(int) बराबर है, क्योंकि अभिव्यक्ति प्रकार int , लेकिन आम तौर पर सी ++ में 1 होती है (हालांकि यह होने की आवश्यकता नहीं है)। अभ्यास में वे लगभग हमेशा अलग होते हैं।

सी और सी ++ में कई अंतर हैं, और सभी वैध सी कोड वैध सी ++ कोड नहीं हैं।
("मान्य" से मेरा मतलब परिभाषित व्यवहार के साथ मानक कोड है, यानी कार्यान्वयन-विशिष्ट / अपरिभाषित / आदि नहीं।)

क्या कोई परिदृश्य है जिसमें सी और सी ++ दोनों में मान्य कोड का एक टुकड़ा अलग-अलग व्यवहार का उत्पादन करेगा जब प्रत्येक भाषा में मानक कंपाइलर के साथ संकलित किया जाता है?

इसे एक उचित / उपयोगी तुलना करने के लिए (मैं कुछ व्यावहारिक रूप से उपयोगी सीखने की कोशिश कर रहा हूं, प्रश्न में स्पष्ट कमी को खोजने की कोशिश न करें), आइए मान लें:

  • कुछ भी प्रीप्रोसेसर से संबंधित नहीं है (जिसका मतलब है #ifdef __cplusplus , pragmas, आदि के साथ कोई हैक्स)
  • कुछ भी कार्यान्वयन-परिभाषित दोनों भाषाओं में समान है (उदाहरण के लिए संख्यात्मक सीमाएं, आदि)
  • हम प्रत्येक मानक के उचित हाल के संस्करणों की तुलना कर रहे हैं (उदाहरण के लिए, सी ++ 98 और सी 0 9 या बाद में)
    यदि संस्करण मायने रखते हैं, तो कृपया प्रत्येक का अलग-अलग संस्करण अलग-अलग व्यवहार का उल्लेख करें।

एक और उदाहरण जिसे मैंने अभी तक नहीं देखा है, यह एक प्रीप्रोसेसर अंतर को हाइलाइट करता है:

#include <stdio.h>
int main()
{
#if true
    printf("true!\n");
#else
    printf("false!\n");
#endif
    return 0;
}

यह सी में "झूठा" और सी ++ में "सत्य" प्रिंट करता है - सी में, कोई अपरिभाषित मैक्रो 0 का मूल्यांकन करता है। सी ++ में, 1 अपवाद होता है: "सत्य" 1 का मूल्यांकन करता है।


निम्न, सी और सी ++ में मान्य, सी (सी ++ में अलग-अलग मानों में (सबसे अधिक संभावना) परिणाम जा रहा है:

int i = sizeof('a');

अंतर के स्पष्टीकरण के लिए सी / सी ++ में चरित्र का आकार ('ए') देखें।

इस लेख से एक और:

#include <stdio.h>

int  sz = 80;

int main(void)
{
    struct sz { char c; };

    int val = sizeof(sz);      // sizeof(int) in C,
                               // sizeof(struct sz) in C++
    printf("%d\n", val);
    return 0;
}

प्रति सी ++ 11 मानक:

ए। अल्पविराम ऑपरेटर सी में lvalue-to-rvalue रूपांतरण करता है लेकिन सी ++ नहीं:

   char arr[100];
   int s = sizeof(0, arr);       // The comma operator is used.

सी ++ में इस अभिव्यक्ति का मूल्य 100 होगा और सी में यह sizeof(char*)

ख। सी ++ में एन्युमरेटर का प्रकार इसकी enum है। सी में गणक के प्रकार int है।

   enum E { a, b, c };
   sizeof(a) == sizeof(int);     // In C
   sizeof(a) == sizeof(E);       // In C++

इसका मतलब है कि sizeof(int) sizeof(E) बराबर नहीं हो सकता है।

सी। सी ++ में खाली पैरा सूची के साथ घोषित एक फ़ंक्शन में कोई तर्क नहीं होता है। सी खाली पैरा सूची में मतलब है कि फ़ंक्शन पैराम की संख्या और प्रकार अज्ञात है।

   int f();           // int f(void) in C++
                      // int f(*unknown*) in C

यहां एक उदाहरण दिया गया है जो सी और सी ++ में फ़ंक्शन कॉल और ऑब्जेक्ट घोषणाओं के बीच अंतर का लाभ उठाता है, साथ ही तथ्य यह है कि C90 अविकसित कार्यों को कॉल करने की अनुमति देता है:

#include <stdio.h>

struct f { int x; };

int main() {
    f();
}

int f() {
    return printf("hello");
}

सी ++ में यह कुछ भी प्रिंट नहीं करेगा क्योंकि अस्थायी f बनाया और नष्ट हो गया है, लेकिन सी 9 0 में यह hello प्रिंट करेगा क्योंकि कार्यों को घोषित किए बिना बुलाया जा सकता है।

यदि आप दो बार इस्तेमाल होने वाले नाम के बारे में सोच रहे थे, तो सी और सी ++ मानकों को स्पष्ट रूप से इसकी अनुमति मिलती है, और यदि आप संरचना चाहते हैं तो किसी ऑब्जेक्ट को संरचनात्मक struct f को असंबद्ध करने के लिए कहें, या यदि आप फ़ंक्शन चाहते हैं तो struct छोड़ दें ।


सी ++ बनाम सी 0 9 के लिए, विभिन्न व्यवहार प्राप्त करने के लिए कम से कम एक तरीका है जो कार्यान्वयन परिभाषित नहीं है। सी 0 9 में सिंगल-लाइन टिप्पणियां नहीं हैं। थोड़ी सी देखभाल के साथ, हम इसका उपयोग C90 में और C ++ में पूरी तरह से अलग परिणामों के साथ अभिव्यक्ति बनाने के लिए कर सकते हैं।

int a = 10 //* comment */ 2 
        + 3;

सी ++ में, // से लेकर लाइन के अंत तक सबकुछ एक टिप्पणी है, इसलिए यह इस प्रकार काम करता है:

int a = 10 + 3;

चूंकि सी 0 9 में सिंगल-लाइन टिप्पणियां नहीं हैं, केवल /* comment */ एक टिप्पणी है। पहला / और 2 प्रारंभिकरण के दोनों भाग हैं, इसलिए यह पता चला है:

int a = 10 / 2 + 3;

तो, एक सही सी ++ कंपाइलर 13 देगा, लेकिन एक सही सी कंपाइलर 8. बेशक, मैंने अभी मनमानी संख्याएं चुनी हैं - आप फिट होने पर अन्य नंबरों का उपयोग कर सकते हैं।


सी 9 0 बनाम सी ++ 11 ( int बनाम double ):

#include <stdio.h>

int main()
{
  auto j = 1.5;
  printf("%d", (int)sizeof(j));
  return 0;
}

सी auto स्थानीय चर का मतलब है। सी 9 0 में परिवर्तनीय या फ़ंक्शन प्रकार को छोड़ना ठीक है। यह int लिए डिफ़ॉल्ट है। सी ++ 11 auto कुछ पूरी तरह से अलग है, यह संकलक को वैरिएबल के प्रकार को अनुमानित करने के लिए उपयोग किए गए मान से अनुमान लगाने के लिए कहता है।


सी और सी ++ वैश्विक नामस्थानों के बीच भेद को मत भूलना। मान लें कि आपके पास foo.cpp है

#include <cstdio>

void foo(int r)
{
  printf("I am C++\n");
}

और एक foo2.c

#include <stdio.h>

void foo(int r)
{
  printf("I am C\n");
}

अब मान लें कि आपके पास main.c और main.cpp है जो दोनों इस तरह दिखते हैं:

extern void foo(int);

int main(void)
{
  foo(1);
  return 0;
}

सी ++ के रूप में संकलित होने पर, यह सी ++ वैश्विक नामस्थान में प्रतीक का उपयोग करेगा; सी में यह सी का उपयोग करेगा:

$ diff main.cpp main.c
$ gcc -o test main.cpp foo.cpp foo2.c
$ ./test 
I am C++
$ gcc -o test main.c foo.cpp foo2.c
$ ./test 
I am C

सी ++ प्रोग्रामिंग भाषा (तीसरा संस्करण) तीन उदाहरण देता है:

  1. आकार ('ए'), जैसा कि @ एडम रोसेनफील्ड ने उल्लेख किया है;

  2. // टिप्पणी छुपा कोड बनाने के लिए इस्तेमाल किया जा रहा है:

    int f(int a, int b)
    {
        return a //* blah */ b
            ;
    }
    
  3. स्ट्रक्चर इत्यादि। आपके उदाहरण में, बाहर के क्षेत्रों में सामान छिपाना।


#include <stdio.h>

int main(void)
{
    printf("%d\n", (int)sizeof('a'));
    return 0;
}

सी में, यह प्रिंट जो भी sizeof(int) का मान वर्तमान प्रणाली पर है, जो आम तौर पर आमतौर पर उपयोग में जाने वाली अधिकांश प्रणालियों में 4 होता है।

सी ++ में, इसे 1 प्रिंट करना होगा।


struct abort
{
    int x;
};

int main()
{
    abort();
    return 0;
}

सी ++ में 0 के बाहर निकलने वाले कोड के साथ वापस आता है, या सी में 3।

इस चाल का उपयोग शायद कुछ और दिलचस्प करने के लिए किया जा सकता था, लेकिन मैं एक कन्स्ट्रक्टर बनाने का एक अच्छा तरीका नहीं सोच सकता था जो कि सी के लिए अनुकूल होगा। मैंने कॉपी कन्स्ट्रक्टर के साथ एक समान उबाऊ उदाहरण बनाने की कोशिश की, जो एक तर्क देगी एक गैर पोर्टेबल फैशन में यद्यपि पारित किया जाना चाहिए:

struct exit
{
    int x;
};

int main()
{
    struct exit code;
    code.x=1;

    exit(code);

    return 0;
}

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





c