दिलचस्प पोस्ट
intl एक्सटेंशन: स्थापित php_intl.dll पायथन में stdout पर मुद्रित करने के लिए सी साझा लाइब्रेरी को मैं कैसे रोकूं? कैनवस के आसपास कार्य करें। क्लिपपाथ () जो एंड्रॉइड में और अधिक समर्थित नहीं है स्क्रिप्ट मैनेजर को किसी भी नियंत्रण की आवश्यकता होती है जो इसकी आवश्यकता होती है लॉगिंग, स्ट्रीमहाण्डलर और मानक स्ट्रीम क्या फ़ाइल के पुराने संस्करण को देखने के लिए एक त्वरित git कमांड है? एकाधिक एलएचएस के साथ एक रैखिक मॉडल फिटिंग मैट्रिक्स को 3-स्तंभ तालिका में परिवर्तित करें ('रिवर्स धुएं', 'अनपिवट', 'फ्लैटेन', 'सामान्य') हॉवर के बाद माउस को एनीमेशन पर वापस कैसे जाना चाहिए Matplotlib में एक (यादृच्छिक) * .otf या * .ttf फ़ॉन्ट का उपयोग कैसे करें? क्या मैं schema.org रिच स्निपेट्स के लिए स्पैन टैग में एकाधिक आइटम पर्च का उपयोग कर सकता हूं? यानी 9 सीमा त्रिज्या डेटाबेस में परिवर्तन क्यों सहेजता है? मैं Node.js अनुप्रयोगों को डिबग कैसे कर सकता हूँ? स्विफ्ट बनाम जावा एफएक्स डेस्कटॉप अनुप्रयोगों के लिए

क्या लोगों को सी / सी ++ में बना हुआ अनुचित मान्यताओं का प्रदर्शन करने के लिए एक शैक्षिक उपकरण का क्या है?

मैं एक छोटे शैक्षिक उपकरण तैयार करना चाहता हूं ताकि सी, सी + + और उनके प्लेटफार्मों में अपने अनुचित मान्यताओं को पहचान और चुनौती देने के लिए शुरुआती (और मध्यवर्ती) प्रोग्रामर्स को सहायता करनी चाहिए।

उदाहरण:

  • "पूर्णांक लपेटो"
  • "सभी को एएससीआईआई है"
  • "मैं फ़ंक्शन पॉइंटर को शून्य में संग्रहीत कर सकता हूँ"

मुझे लगा कि एक छोटे से परीक्षण कार्यक्रम विभिन्न प्लेटफार्मों पर चलाया जा सकता है, जो कि "प्रशंसनीय" मान्यताओं को चलाता है, जो कि SOO में हमारे अनुभव से होता है, आमतौर पर कई अनुभवहीन / सेमेक्सिएरिअड मुख्यधारा के डेवलपर्स द्वारा किए जाते हैं और विभिन्न मशीनों पर वे तरीके तोड़ते हैं।

इसका लक्ष्य यह साबित करने के लिए नहीं है कि यह कुछ करने के लिए "सुरक्षित" है (जो करना असंभव होगा, परीक्षण केवल कुछ भी साबित करते हैं यदि वे तोड़ते हैं), लेकिन इसके बजाय यह सबसे बेहिचक व्यक्ति को भी प्रदर्शित करने के लिए कैसे सबसे अगोचर अभिव्यक्ति एक अलग मशीन पर ब्रेक करें, अगर इसमें एक अपरिभाषित या कार्यान्वयन परिभाषित व्यवहार होता है

इसे प्राप्त करने के लिए मैं आपको पूछना चाहूंगा:

  • इस विचार को कैसे सुधार किया जा सकता है?
  • कौन से परीक्षण अच्छे होंगे और उन्हें कैसा दिखना चाहिए?
  • क्या आप प्लेटफार्मों पर परीक्षण चलाते हैं, जिससे आप अपने हाथों को प्राप्त कर सकते हैं और परिणाम पोस्ट कर सकते हैं, ताकि हम प्लेटफार्मों के एक डेटाबेस के साथ समाप्त हो जाएं, ये कैसे भिन्न होते हैं और यह अंतर क्यों अनुमति देता है?

यहाँ परीक्षण खिलौने के लिए वर्तमान संस्करण है:

#include <stdio.h> #include <limits.h> #include <stdlib.h> #include <stddef.h> int count=0; int total=0; void expect(const char *info, const char *expr) { printf("..%s\n but '%s' is false.\n",info,expr); fflush(stdout); count++; } #define EXPECT(INFO,EXPR) if (total++,!(EXPR)) expect(INFO,#EXPR) /* stack check..How can I do this better? */ ptrdiff_t check_grow(int k, int *p) { if (p==0) p=&k; if (k==0) return &k-p; else return check_grow(k-1,p); } #define BITS_PER_INT (sizeof(int)*CHAR_BIT) int bits_per_int=BITS_PER_INT; int int_max=INT_MAX; int int_min=INT_MIN; /* for 21 - left to right */ int ltr_result=0; unsigned ltr_fun(int k) { ltr_result=ltr_result*10+k; return 1; } int main() { printf("We like to think that:\n"); /* characters */ EXPECT("00 we have ASCII",('A'==65)); EXPECT("01 AZ is in a block",('Z'-'A')+1==26); EXPECT("02 big letters come before small letters",('A'<'a')); EXPECT("03 a char is 8 bits",CHAR_BIT==8); EXPECT("04 a char is signed",CHAR_MIN==SCHAR_MIN); /* integers */ EXPECT("05 int has the size of pointers",sizeof(int)==sizeof(void*)); /* not true for Windows-64 */ EXPECT("05a long has at least the size of pointers",sizeof(long)>=sizeof(void*)); EXPECT("06 integers are 2-complement and wrap around",(int_max+1)==(int_min)); EXPECT("07 integers are 2-complement and *always* wrap around",(INT_MAX+1)==(INT_MIN)); EXPECT("08 overshifting is okay",(1<<bits_per_int)==0); EXPECT("09 overshifting is *always* okay",(1<<BITS_PER_INT)==0); { int t; EXPECT("09a minus shifts backwards",(t=-1,(15<<t)==7)); } /* pointers */ /* Suggested by jalf */ EXPECT("10 void* can store function pointers",sizeof(void*)>=sizeof(void(*)())); /* execution */ EXPECT("11 Detecting how the stack grows is easy",check_grow(5,0)!=0); EXPECT("12 the stack grows downwards",check_grow(5,0)<0); { int t; /* suggested by jk */ EXPECT("13 The smallest bits always come first",(t=0x1234,0x34==*(char*)&t)); } { /* Suggested by S.Lott */ int a[2]={0,0}; int i=0; EXPECT("14 i++ is strictly left to right",(i=0,a[i++]=i,a[0]==1)); } { struct { char c; int i; } char_int; EXPECT("15 structs are packed",sizeof(char_int)==(sizeof(char)+sizeof(int))); } { EXPECT("16 malloc()=NULL means out of memory",(malloc(0)!=NULL)); } /* suggested by David Thornley */ EXPECT("17 size_t is unsigned int",sizeof(size_t)==sizeof(unsigned int)); /* this is true for C99, but not for C90. */ EXPECT("18 a%b has the same sign as a",((-10%3)==-1) && ((10%-3)==1)); /* suggested by nos */ EXPECT("19-1 char<short",sizeof(char)<sizeof(short)); EXPECT("19-2 short<int",sizeof(short)<sizeof(int)); EXPECT("19-3 int<long",sizeof(int)<sizeof(long)); EXPECT("20 ptrdiff_t and size_t have the same size",(sizeof(ptrdiff_t)==sizeof(size_t))); #if 0 { /* suggested by R. */ /* this crashed on TC 3.0++, compact. */ char buf[10]; EXPECT("21 You can use snprintf to append a string", (snprintf(buf,10,"OK"),snprintf(buf,10,"%s!!",buf),strcmp(buf,"OK!!")==0)); } #endif EXPECT("21 Evaluation is left to right", (ltr_fun(1)*ltr_fun(2)*ltr_fun(3)*ltr_fun(4),ltr_result==1234)); { #ifdef __STDC_IEC_559__ int STDC_IEC_559_is_defined=1; #else /* This either means, there is no FP support *or* the compiler is not C99 enough to define __STDC_IEC_559__ *or* the FP support is not IEEE compliant. */ int STDC_IEC_559_is_defined=0; #endif EXPECT("22 floating point is always IEEE",STDC_IEC_559_is_defined); } printf("From what I can say with my puny test cases, you are %d%% mainstream\n",100-(100*count)/total); return 0; } 

ओह, और मैंने इस सामुदायिक विकी को शुरू से ही बनाया है क्योंकि मैंने सोचा था कि जब लोग इसे पढ़ते हैं तो लोग मेरे बड़बड़ाना को संपादित करना चाहते हैं।

अद्यतन आपके इनपुट के लिए धन्यवाद मैंने आपके उत्तर से कुछ मामलों को जोड़ लिया है और यह देखेगा कि क्या मैं इस तरह ग्रेग की तरह एक गिथबुल स्थापित कर सकता हूं।

अद्यतनः मैंने इसके लिए एक गिथूब रेपो बनाया है, फ़ाइल "gotcha.c" है:

  • http://github.com/lutherblissett/disenchanter

कृपया पैच या नए विचारों के साथ यहां उत्तर दें, इसलिए उन्हें यहां चर्चा या स्पष्ट किया जा सकता है मैं उन्हें मिलाकर सी में मिला दूंगा।

वेब के समाधान से एकत्रित समाधान "क्या लोगों को सी / सी ++ में बना हुआ अनुचित मान्यताओं का प्रदर्शन करने के लिए एक शैक्षिक उपकरण का क्या है?"

सहित subexpressions के मूल्यांकन के आदेश, सहित

  • फ़ंक्शन कॉल के तर्क और
  • इसके अपवाद के साथ ऑपरेटरों के ऑपरेट (उदा।, + , - , = , * , / )
    • बाइनरी लॉजिकल ऑपरेटर्स ( && और || ),
    • टर्नरी सशर्त ऑपरेटर ( ?: :), और
    • कॉमा ऑपरेटर ( , )

अनिर्दिष्ट है

उदाहरण के लिए

  int Hello() { return printf("Hello"); /* printf() returns the number of characters successfully printed by it */ } int World() { return printf("World !"); } int main() { int a = Hello() + World(); //might print Hello World! or World! Hello /** ^ | Functions can be called in either order **/ return 0; } 

एसडीसीसी 29.7 / ucSim / Z80

 We like to think that: ..09a minus shifts backwards but '(t=-1,(15<<t)==7)' is false. ..19-2 short<int but 'sizeof(short)<sizeof(int)' is false. ..22 floating point is always IEEE but 'STDC_IEC_559_is_defined' is false. ..25 pointer arithmetic works outside arrays but '(diff=&var.int2-&var.int1, &var.int1+diff==&var.int2)' is false. From what I can say with my puny test cases, you are Stop at 0x0013f3: (106) Invalid instruction 0x00dd 

printf क्रैश "O_O"


जीसीसी 4.4@x86_64-suse-linux

 We like to think that: ..05 int has the size of pointers but 'sizeof(int)==sizeof(void*)' is false. ..08 overshifting is okay but '(1<<bits_per_int)==0' is false. ..09a minus shifts backwards but '(t=-1,(15<<t)==7)' is false. ..14 i++ is strictly left to right but '(i=0,a[i++]=i,a[0]==1)' is false. ..15 structs are packed but 'sizeof(char_int)==(sizeof(char)+sizeof(int))' is false. ..17 size_t is unsigned int but 'sizeof(size_t)==sizeof(unsigned int)' is false. ..26 sizeof() does not evaluate its arguments but '(i=10,sizeof(char[((i=20),10)]),i==10)' is false. From what I can say with my puny test cases, you are 79% mainstream 

gcc 4.4@x86_64-suse-linux (-O2)

 We like to think that: ..05 int has the size of pointers but 'sizeof(int)==sizeof(void*)' is false. ..08 overshifting is okay but '(1<<bits_per_int)==0' is false. ..14 i++ is strictly left to right but '(i=0,a[i++]=i,a[0]==1)' is false. ..15 structs are packed but 'sizeof(char_int)==(sizeof(char)+sizeof(int))' is false. ..17 size_t is unsigned int but 'sizeof(size_t)==sizeof(unsigned int)' is false. ..26 sizeof() does not evaluate its arguments but '(i=10,sizeof(char[((i=20),10)]),i==10)' is false. From what I can say with my puny test cases, you are 82% mainstream 

क्लैग 2.7@x86_64-suse-linux

 We like to think that: ..05 int has the size of pointers but 'sizeof(int)==sizeof(void*)' is false. ..08 overshifting is okay but '(1<<bits_per_int)==0' is false. ..09a minus shifts backwards but '(t=-1,(15<<t)==7)' is false. ..14 i++ is strictly left to right but '(i=0,a[i++]=i,a[0]==1)' is false. ..15 structs are packed but 'sizeof(char_int)==(sizeof(char)+sizeof(int))' is false. ..17 size_t is unsigned int but 'sizeof(size_t)==sizeof(unsigned int)' is false. ..21a Function Arguments are evaluated right to left but '(gobble_args(0,ltr_fun(1),ltr_fun(2),ltr_fun(3),ltr_fun(4)),ltr_result==4321)' is false. ltr_result is 1234 in this case ..25a pointer arithmetic works outside arrays but '(diff=&p1-&p2, &p2+diff==&p1)' is false. ..26 sizeof() does not evaluate its arguments but '(i=10,sizeof(char[((i=20),10)]),i==10)' is false. From what I can say with my puny test cases, you are 72% mainstream 

open64 4.2.3@x86_64-suse-linux

 We like to think that: ..05 int has the size of pointers but 'sizeof(int)==sizeof(void*)' is false. ..08 overshifting is okay but '(1<<bits_per_int)==0' is false. ..09a minus shifts backwards but '(t=-1,(15<<t)==7)' is false. ..15 structs are packed but 'sizeof(char_int)==(sizeof(char)+sizeof(int))' is false. ..17 size_t is unsigned int but 'sizeof(size_t)==sizeof(unsigned int)' is false. ..21a Function Arguments are evaluated right to left but '(gobble_args(0,ltr_fun(1),ltr_fun(2),ltr_fun(3),ltr_fun(4)),ltr_result==4321)' is false. ltr_result is 1234 in this case ..25a pointer arithmetic works outside arrays but '(diff=&p1-&p2, &p2+diff==&p1)' is false. ..26 sizeof() does not evaluate its arguments but '(i=10,sizeof(char[((i=20),10)]),i==10)' is false. From what I can say with my puny test cases, you are 75% mainstream 

इंटेल 11.1@x86_64-suse-linux

 We like to think that: ..05 int has the size of pointers but 'sizeof(int)==sizeof(void*)' is false. ..08 overshifting is okay but '(1<<bits_per_int)==0' is false. ..09a minus shifts backwards but '(t=-1,(15<<t)==7)' is false. ..14 i++ is strictly left to right but '(i=0,a[i++]=i,a[0]==1)' is false. ..15 structs are packed but 'sizeof(char_int)==(sizeof(char)+sizeof(int))' is false. ..17 size_t is unsigned int but 'sizeof(size_t)==sizeof(unsigned int)' is false. ..21a Function Arguments are evaluated right to left but '(gobble_args(0,ltr_fun(1),ltr_fun(2),ltr_fun(3),ltr_fun(4)),ltr_result==4321)' is false. ltr_result is 1234 in this case ..26 sizeof() does not evaluate its arguments but '(i=10,sizeof(char[((i=20),10)]),i==10)' is false. From what I can say with my puny test cases, you are 75% mainstream 

टर्बो सी ++ / डॉस / स्मॉल मेमोरी

 We like to think that: ..09a minus shifts backwards but '(t=-1,(15<<t)==7)' is false. ..16 malloc()=NULL means out of memory but '(malloc(0)!=NULL)' is false. ..19-2 short<int but 'sizeof(short)<sizeof(int)' is false. ..22 floating point is always IEEE but 'STDC_IEC_559_is_defined' is false. ..25 pointer arithmetic works outside arrays but '(diff=&var.int2-&var.int1, &var.int1+diff==&var.int2)' is false. ..25a pointer arithmetic works outside arrays but '(diff=&p1-&p2, &p2+diff==&p1)' is false. From what I can say with my puny test cases, you are 81% mainstream 

टर्बो सी ++ / डॉस / मध्यम मेमोरी

 We like to think that: ..09a minus shifts backwards but '(t=-1,(15<<t)==7)' is false. ..10 void* can store function pointers but 'sizeof(void*)>=sizeof(void(*)())' is false. ..16 malloc()=NULL means out of memory but '(malloc(0)!=NULL)' is false. ..19-2 short<int but 'sizeof(short)<sizeof(int)' is false. ..22 floating point is always IEEE but 'STDC_IEC_559_is_defined' is false. ..25 pointer arithmetic works outside arrays but '(diff=&var.int2-&var.int1, &var.int1+diff==&var.int2)' is false. ..25a pointer arithmetic works outside arrays but '(diff=&p1-&p2, &p2+diff==&p1)' is false. From what I can say with my puny test cases, you are 78% mainstream 

टर्बो सी ++ / डॉस / कॉम्पैक्ट मेमोरी

 We like to think that: ..05 int has the size of pointers but 'sizeof(int)==sizeof(void*)' is false. ..09a minus shifts backwards but '(t=-1,(15<<t)==7)' is false. ..16 malloc()=NULL means out of memory but '(malloc(0)!=NULL)' is false. ..19-2 short<int but 'sizeof(short)<sizeof(int)' is false. ..20 ptrdiff_t and size_t have the same size but '(sizeof(ptrdiff_t)==sizeof(size_t))' is false. ..22 floating point is always IEEE but 'STDC_IEC_559_is_defined' is false. ..25 pointer arithmetic works outside arrays but '(diff=&var.int2-&var.int1, &var.int1+diff==&var.int2)' is false. ..25a pointer arithmetic works outside arrays but '(diff=&p1-&p2, &p2+diff==&p1)' is false. From what I can say with my puny test cases, you are 75% mainstream 

सीएल 65 @ कमोडोर पीईटी (उप एमुलेटर)

वैकल्पिक पाठ http://img.hiwab.com/c%2B%2B/2hh0zmc.png


मैं इन्हें बाद में अपडेट कर रहा हूं:


विंडोज एक्सपी पर बोरोलैंड सी ++ बिल्डर 6.0

 ..04 a char is signed but 'CHAR_MIN==SCHAR_MIN' is false. ..08 overshifting is okay but '(1<<bits_per_int)==0' is false. ..09 overshifting is *always* okay but '(1<<BITS_PER_INT)==0' is false. ..09a minus shifts backwards but '(t=-1,(15<<t)==7)' is false. ..15 structs are packed but 'sizeof(char_int)==(sizeof(char)+sizeof(int))' is false. ..16 malloc()=NULL means out of memory but '(malloc(0)!=NULL)' is false. ..19-3 int<long but 'sizeof(int)<sizeof(long)' is false. ..22 floating point is always IEEE but 'STDC_IEC_559_is_defined' is false. From what I can say with my puny test cases, you are 71% mainstream 

विज़ुअल स्टूडियो एक्सप्रेस 2010 सी + सीएलआर, विंडोज 7 64 बिट

(सी + + के रूप में संकलित होना चाहिए क्योंकि सीएलआर कंपाइलर शुद्ध सी का समर्थन नहीं करता है)

 We like to think that: ..08 overshifting is okay but '(1<<bits_per_int)==0' is false. ..09a minus shifts backwards but '(t=-1,(15<<t)==7)' is false. ..14 i++ is structly left to right but '(i=0,a[i++]=i,a[0]==1)' is false. ..15 structs are packed but 'sizeof(char_int)==(sizeof(char)+sizeof(int))' is false. ..19-3 int<long but 'sizeof(int)<sizeof(long)' is false. ..22 floating point is always IEEE but 'STDC_IEC_559_is_defined' is false. From what I can say with my puny test cases, you are 78% mainstream 

मिंगव 64 (जीसीसी-4.5.2 प्रीरलसेज)

http://mingw-w64.sourceforge.net/

 We like to think that: ..05 int has the size of pointers but 'sizeof(int)==sizeof(void*)' is false. ..05a long has at least the size of pointers but 'sizeof(long)>=sizeof(void*)' is false. ..08 overshifting is okay but '(1<<bits_per_int)==0' is false. ..09a minus shifts backwards but '(t=-1,(15<<t)==7)' is false. ..14 i++ is structly left to right but '(i=0,a[i++]=i,a[0]==1)' is false. ..15 structs are packed but 'sizeof(char_int)==(sizeof(char)+sizeof(int))' is false. ..17 size_t is unsigned int but 'sizeof(size_t)==sizeof(unsigned int)' is false. ..19-3 int<long but 'sizeof(int)<sizeof(long)' is false. ..22 floating point is always IEEE but 'STDC_IEC_559_is_defined' is false. From what I can say with my puny test cases, you are 67% mainstream 

64 बिट विंडोज एलएलपी 64 मॉडल का उपयोग करता है: दोनों int और long को 32-बिट के रूप में परिभाषित किया जाता है, जिसका अर्थ है कि पॉइंटर के लिए न तो काफी लंबा है


avr-gcc 4.3.2 / एटेमेगा 168 (आर्दुइनो डायसीमिला)

असफल मान्यताओं हैं:

 ..14 i++ is structly left to right ..16 malloc()=NULL means out of memory ..19-2 short<int ..21 Evaluation is left to right ..22 floating point is always IEEE 

Atmega168 में एक 16 बिट पीसी है, लेकिन कोड और डेटा अलग पते स्थानों में हैं। बड़ा एटिगास में 22 बिट पीसी है!


जीसीसी 4.2.1 मैकोड 10.6 पर, -पीपीसी के साथ संकलित

 We like to think that: ..09a minus shifts backwards but '(t=-1,(15<<t)==7)' is false. ..13 The smallest bits come always first but '(t=0x1234,0x34==*(char*)&t)' is false. ..14 i++ is structly left to right but '(i=0,a[i++]=i,a[0]==1)' is false. ..15 structs are packed but 'sizeof(char_int)==(sizeof(char)+sizeof(int))' is false. ..19-3 int<long but 'sizeof(int)<sizeof(long)' is false. ..22 floating point is always IEEE but 'STDC_IEC_559_is_defined' is false. From what I can say with my puny test cases, you are 78% mainstream 

एक लंबे समय से पहले, मैं एक पाठ्यपुस्तक से सी पढ़ा रहा था जो कि था

 printf("sizeof(int)=%d\n", sizeof(int)); 

एक नमूना प्रश्न के रूप में यह एक छात्र के लिए असफल रहा, क्योंकि sizeof मूल्यों के sizeof मूल्यों में size_t नहीं, नहीं, इस क्रियान्वयन पर 16 बिट्स और size_t 32 थी, और यह बड़ा-एंडियन था (प्लेटफ़ॉर्म 680×0-आधारित मैकिनाटोस पर सीधा था। मैंने कहा था कि यह बहुत पहले था।)

आपको ++ और -- मान्यताओं को लोगों को शामिल करने की आवश्यकता है

 a[i++]= i; 

उदाहरण के लिए, वाक्यात्मक रूप से कानूनी है, लेकिन कई कारणों के आधार पर अलग-अलग परिणामों का उत्पादन होता है।

किसी भी वक्तव्य में ++ (या -- ) और एक वेरिएबल जो एक से अधिक बार होता है एक समस्या है।

बहुत ही रोचक!

अन्य चीजें जिनके बारे में मैं सोच सकता हूँ ये जांचना उपयोगी हो सकता है:

  • फंक्शन पॉइंटर्स और डेटा पॉइंटर्स एक ही एड्रेस स्पेस में मौजूद हैं? (हार्वर्ड वास्तुकला मशीनों में ब्रेक करता है जैसे डॉस छोटा मोड। आप नहीं जानते कि आप इसके लिए कैसे परीक्षण करेंगे।)

  • यदि आप एक नल डेटा पॉइंटर लेते हैं और इसे उपयुक्त पूर्णांक प्रकार में डालते हैं, तो क्या इसकी संख्यात्मक मान 0 है? (कुछ वास्तविक प्राचीन मशीनों पर तोड़ता है — http://c-faq.com/null/machexamp.html देखें) फ़ंक्शन पॉइंटर के साथ भी। इसके अलावा, वे अलग-अलग मूल्य भी हो सकते हैं।

  • अपनी संगत स्टोरेज ऑब्जेक्ट के अंत में एक पॉइंटर को बढ़ाना, और फिर वापस, समझदार परिणाम का कारण बनता है? (मुझे नहीं पता कि यह किसी मशीन पर वास्तव में टूट जाती है, लेकिन मेरा मानना ​​है कि सी स्पेक आपको पॉइंटर्स के बारे में सोचने की अनुमति नहीं देता जो कि या तो (ए) एक सरणी की सामग्री या (बी) तत्व सरणी या (सी) नल के तुरंत बाद। देखें http://c-faq.com/yripr/non0based.html ।)

  • क्या दो बिंदुओं की तुलना अलग भंडारण ऑब्जेक्ट के साथ करता है <और> लगातार परिणाम उत्पन्न करता है? (मैं इस पर विदेशी खंड-आधारित मशीनों को तोड़ने की कल्पना कर सकता हूं; कल्पना ऐसे तुलनाओं को रोकती है, इसलिए संकलक को केवल सूचक के ऑफसेट भाग की तुलना करने के लिए, और सेगमेंट भाग की तुलना करने का हकदार होगा।)

हम्म। मैं कुछ और कोशिश करूँगा और सोचूंगा।

संपादित करें: उत्कृष्ट सी सामान्य प्रश्न के लिए कुछ स्पष्टता लिंक जोड़ा गया।

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

खैर क्लासिक पोर्टेबिलिटी मान्यताओं का मतलब अभी तक नहीं है

  • अभिन्न प्रकार के आकार के बारे में धारणाएं
  • endianness
  • फ्लोटिंग प्वाइंट प्रेजेंटेशन के कारण विच्छेदन की त्रुटियां उदाहरण के लिए, यदि आप वर्गिक समीकरणों को हल करने के लिए मानक सूत्र का उपयोग करते हैं, या अनुमानित डेरिवेटिव के लिए सीमांत अंतर, या भिन्नताओं की गणना के लिए मानक सूत्र, समान संख्या के बीच अंतर की गणना के कारण सटीकता खो जाएगी। रेखीय प्रणाली को हल करने के लिए गौज एल्गोरिथ्म खराब है क्योंकि गोल की त्रुटियां जमा होती हैं, इस प्रकार कोई क्यूआर या लू अपघटन का उपयोग करता है, चोलस्की अपघटन, एसवीडी, आदि। अस्थायी बिंदु संख्याओं को जोड़ना सहकारी नहीं है। वहाँ विकृत, अनंत और ना एनएन मान हैं + बीबी

  • स्ट्रिंग: वर्णों, कोड बिंदुओं और कोड इकाइयों में अंतर। विभिन्न ऑपरेटिंग सिस्टम पर यूनिकोड कैसे लागू होता है; यूनिकोड एन्कोडिंग एक अनौपचारिक यूनिकोड फाइल नाम के साथ फाइल को खोलना पोर्टेबल तरीके से सी ++ के साथ संभव नहीं है।

  • रेस की स्थिति, थ्रेडिंग के बिना भी: यदि आप जांचते हैं कि कोई फ़ाइल मौजूद है या नहीं, तो परिणाम किसी भी समय अमान्य हो सकता है।

  • ERROR_SUCCESS = 0

यहाँ एक मजेदार एक है: इस समारोह में क्या गलत है?

 float sum(unsigned int n, ...) { float v = 0; va_list ap; va_start(ap, n); while (n--) v += va_arg(ap, float); va_end(ap); return v; } 

[उत्तर (रोट 13): इनव्नकविप नेथज़राग्फ बोरल गुर बार्क एक्स एंड ई सेबबग्वा इहर्फ, जिवपु ज़्रनएफ़ एलबीएच पानाबग एचएफआर 'सिबेंग' ('पिन' होना 'फ्यूइंग') वीए इन_नेट! नाक गुर पीबीसीवीर वीएफ एरडवर्क एजी जीबी गर्नग ग्वाफ़ एनएफ एन पीबीज़सीवीर-जीवीजआर रीबे (टीपीपी क्यूब्रफ़ रेजविग एन जनेवत, गुब्तु।)]

 EXPECT("## pow() gives exact results for integer arguments", pow(2, 4) == 16); 

दूसरा एक fopen में टेक्स्ट मोड के बारे में है। अधिकांश प्रोग्रामर यह मानते हैं कि पाठ और बाइनरी समान हैं (यूनिक्स) या उस पाठ मोड में \r वर्ण (विंडोज) शामिल हैं लेकिन सी को उन सिस्टमों पर रख दिया गया है जो तय-चौड़ाई के रिकॉर्ड का उपयोग करते हैं, जिस पर एक पाठ फ़ाइल पर fputc('\n', file) अर्थ है रिक्त स्थान का एक fputc('\n', file) फ़ाइल आकार जब तक कि रिक्त स्थान या कुछ जोड़ने के लिए नहीं।

और यहां मेरे परिणाम हैं:

जीसीसी (Ubuntu 4.4.3-4ubuntu5) x86-64 पर 4.4.3

 We like to think that: ..05 int has the size of pointers but 'sizeof(int)==sizeof(void*)' is false. ..08 overshifting is okay but '(1<<bits_per_int)==0' is false. ..09a minus shifts backwards but '(t=-1,(15<<t)==7)' is false. ..14 i++ is strictly left to right but '(i=0,a[i++]=i,a[0]==1)' is false. ..15 structs are packed but 'sizeof(char_int)==(sizeof(char)+sizeof(int))' is false. ..17 size_t is unsigned int but 'sizeof(size_t)==sizeof(unsigned int)' is false. From what I can say with my puny test cases, you are 78% mainstream 

उनमें से कुछ को आसानी से सी के अंदर से परीक्षण नहीं किया जा सकता क्योंकि कार्यक्रम के कार्यान्वयन पर दुर्घटना होने की संभावना है, जहां धारणा नहीं है।


"पॉइंटर-वैल्यूएबल व्हेरिएबल के साथ कुछ भी करने के लिए ठीक है। यदि आप dereference में हैं, तो उसे केवल एक वैध पॉइंटर मान रखना होगा।"

 void noop(void *p); /* A no-op function that the compiler doesn't know to optimize away */ int main () { char *p = malloc(1); free(p); noop(p); /* may crash in implementations that verify pointer accesses */ noop(p - 42000); /* and if not the previous instruction, maybe this one */ } 

अभिन्न और अस्थायी बिंदु प्रकार ( unsigned char ) के साथ, जो कि जाल अभ्यावेदन करने की अनुमति है।


"इंटीजर गणना पूरी तरह लपेटता है। इसलिए यह प्रोग्राम बड़े नकारात्मक पूर्णांक को प्रिंट करता है।"

 #include <stdio.h> int main () { printf("%d\n", INT_MAX+1); /* may crash due to signed integer overflow */ return 0; } 

(केवल C89।) " main के अंत में गिरना ठीक है।"

 #include <stdio.h> int main () { puts("Hello."); } /* The status code is 7 on many implementations. */ 

पूर्णांक आकारों के लिए एक चेक शामिल करें ज्यादातर लोग यह मानते हैं कि इंट एक छोटा से बड़ा है जो एक चार से बड़ा है। हालांकि, ये सभी गलत हो सकते हैं: sizeof(char) < sizeof(int); sizeof(short) < sizeof(int); sizeof(char) < sizeof(short) sizeof(char) < sizeof(int); sizeof(short) < sizeof(int); sizeof(char) < sizeof(short)

यह कोड विफल हो सकता है (अनियंत्रित पहुंच में क्रैश)

 unsigned char buf[64]; int i = 234; int *p = &buf[1]; *p = i; i = *p; 

अंतर्निहित डेटा प्रकारों के बारे में कुछ चीजें:

  • char और signed char वास्तव में दो अलग प्रकार हैं ( int और signed int विपरीत जो कि एक ही हस्ताक्षरित पूर्णांक प्रकार का संदर्भ देते हैं)।
  • हस्ताक्षरित पूर्णांक दो पूरकों का उपयोग करने के लिए आवश्यक नहीं हैं लोगों का पूरक और साइन + परिमाण नकारात्मक संख्याओं के वैध प्रतिनिधित्व भी हैं यह नकारात्मक संख्याओं को कार्यान्वयन-परिभाषित करते हुए थोड़ा-सा संचालन करता है
  • यदि आप किसी आउट-ऑफ-रेंज पूर्णांक को एक हस्ताक्षरित पूर्णांक चर में निर्दिष्ट करते हैं, तो व्यवहार कार्यान्वयन-परिभाषित है
  • सी 90 में, -3/5 0 या -1 वापस कर सकते हैं शून्य के मुकाबले गोलाई के मामले में एक ऑपरेंड नकारात्मक था केवल C99 ऊपर की ओर और C ++ 0x ऊपर की गारंटी दी गई है।
  • अंतर्निहित प्रकारों के लिए कोई सटीक आकार की गारंटी नहीं है। मानक में केवल न्यूनतम आवश्यकताओं को शामिल किया गया है जैसे कि किसी int में कम से कम 16 बिट्स होते हैं, एक long कम से कम 32 बिट्स होते हैं, एक long long कम से कम 64 बिट्स होते हैं। एक float कम से कम 6 सबसे महत्वपूर्ण दशमलव अंकों का सही ढंग से प्रतिनिधित्व कर सकता है एक double कम से कम 10 सबसे महत्वपूर्ण दशमलव अंकों का सही ढंग से प्रतिनिधित्व कर सकता है
  • आईईईई 754 फ्लोटिंग प्वाइंट नंबर का प्रतिनिधित्व करने के लिए अनिवार्य नहीं है।

बेशक, अधिकांश मशीनों पर हमारे पास दो पूरक और आईईईई 754 फ़्लोट्स होंगे।

संपादित करें: प्रोग्राम के अंतिम संस्करण में अपडेट किया गया

सोलारिस-स्पार्क

32.6 में जीसीसी 3.4.6 में

 We like to think that: ..08 overshifting is okay but '(1<<bits_per_int)==0' is false. ..09 overshifting is *always* okay but '(1<<BITS_PER_INT)==0' is false. ..09a minus shifts backwards but '(t=-1,(15<<t)==7)' is false. ..13 The smallest bits always come first but '(t=0x1234,0x34==*(char*)&t)' is false. ..14 i++ is strictly left to right but '(i=0,a[i++]=i,a[0]==1)' is false. ..15 structs are packed but 'sizeof(char_int)==(sizeof(char)+sizeof(int))' is false. ..19-3 int<long but 'sizeof(int)<sizeof(long)' is false. ..22 floating point is always IEEE but 'STDC_IEC_559_is_defined' is false. From what I can say with my puny test cases, you are 72% mainstream 

64.6 में जीसीसी 3.4.6

 We like to think that: ..05 int has the size of pointers but 'sizeof(int)==sizeof(void*)' is false. ..08 overshifting is okay but '(1<<bits_per_int)==0' is false. ..09 overshifting is *always* okay but '(1<<BITS_PER_INT)==0' is false. ..09a minus shifts backwards but '(t=-1,(15<<t)==7)' is false. ..13 The smallest bits always come first but '(t=0x1234,0x34==*(char*)&t)' is false. ..14 i++ is strictly left to right but '(i=0,a[i++]=i,a[0]==1)' is false. ..15 structs are packed but 'sizeof(char_int)==(sizeof(char)+sizeof(int))' is false. ..17 size_t is unsigned int but 'sizeof(size_t)==sizeof(unsigned int)' is false. ..22 floating point is always IEEE but 'STDC_IEC_559_is_defined' is false. From what I can say with my puny test cases, you are 68% mainstream 

और सनस्ट्यूडियो 11 32 बिट के साथ

 We like to think that: ..08 overshifting is okay but '(1<<bits_per_int)==0' is false. ..09a minus shifts backwards but '(t=-1,(15<<t)==7)' is false. ..13 The smallest bits always come first but '(t=0x1234,0x34==*(char*)&t)' is false. ..14 i++ is strictly left to right but '(i=0,a[i++]=i,a[0]==1)' is false. ..15 structs are packed but 'sizeof(char_int)==(sizeof(char)+sizeof(int))' is false. ..19-3 int<long but 'sizeof(int)<sizeof(long)' is false. From what I can say with my puny test cases, you are 79% mainstream 

और सनस्ट्यूडियो 11 64 बिट के साथ

 We like to think that: ..05 int has the size of pointers but 'sizeof(int)==sizeof(void*)' is false. ..08 overshifting is okay but '(1<<bits_per_int)==0' is false. ..09a minus shifts backwards but '(t=-1,(15<<t)==7)' is false. ..13 The smallest bits always come first but '(t=0x1234,0x34==*(char*)&t)' is false. ..14 i++ is strictly left to right but '(i=0,a[i++]=i,a[0]==1)' is false. ..15 structs are packed but 'sizeof(char_int)==(sizeof(char)+sizeof(int))' is false. ..17 size_t is unsigned int but 'sizeof(size_t)==sizeof(unsigned int)' is false. From what I can say with my puny test cases, you are 75% mainstream 

इसके बारे में क्या खयाल है:

No data pointer can ever be the same as a valid function pointer.

This is TRUE for all flat models, MS-DOS TINY, LARGE, and HUGE models, false for MS-DOS SMALL model, and almost always false for MEDIUM and COMPACT models (depends on load address, you will need a really old DOS to make it true).

I can't write a test for this

And worse: pointers casted to ptrdiff_t may be compared. This not true for MS-DOS LARGE model (the only difference between LARGE and HUGE is HUGE adds compiler code to normalize pointers).

I can't write a test because the environment where this bombs hard won't allocate a buffer greater than 64K so the code that demonstrates it would crash on other platforms.

This particular test would pass on one now-defunct system (notice it depends on the internals of malloc):

  char *ptr1 = malloc(16); char *ptr2 = malloc(16); if ((ptrdiff_t)ptr2 - 0x20000 == (ptrdiff_t)ptr1) printf("We like to think that unrelated pointers are equality comparable when cast to the appropriate integer, but they're not."); 

You can use text-mode ( fopen("filename", "r") ) to read any sort of text file.

While this should in theory work just fine, if you also use ftell() in your code, and your text file has UNIX-style line-endings, in some versions of the Windows standard library, ftell() will often return invalid values. The solution is to use binary mode instead ( fopen("filename", "rb") ).

gcc 3.3.2 on AIX 5.3 (yeah, we need to update gcc)

 We like to think that: ..04 a char is signed but 'CHAR_MIN==SCHAR_MIN' is false. ..09a minus shifts backwards but '(t=-1,(15<<t)==7)' is false. ..13 The smallest bits come always first but '(t=0x1234,0x34==*(char*)&t)' is false. ..14 i++ is structly left to right but '(i=0,a[i++]=i,a[0]==1)' is false. ..15 structs are packed but 'sizeof(char_int)==(sizeof(char)+sizeof(int))' is false. ..16 malloc()=NULL means out of memory but '(malloc(0)!=NULL)' is false. ..19-3 int<long but 'sizeof(int)<sizeof(long)' is false. ..22 floating point is always IEEE but 'STDC_IEC_559_is_defined' is false. From what I can say with my puny test cases, you are 71% mainstream 

An assumption that some may do in C++ is that a struct is limited to what it can do in C. The fact is that, in C++, a struct is like a class except that it has everything public by default.

C++ struct:

 struct Foo { int number1_; //this is public by default //this is valid in C++: private: void Testing1(); int number2_; protected: void Testing2(); }; 

Standard math functions on different systems don't give identical results.

Visual Studio Express 2010 on 32-bit x86.

 Z:\sandbox>cl testtoy.c Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. testtoy.c testtoy.c(54) : warning C4293: '<<' : shift count negative or too big, undefined behavior Microsoft (R) Incremental Linker Version 10.00.30319.01 Copyright (C) Microsoft Corporation. All rights reserved. /out:testtoy.exe testtoy.obj Z:\sandbox>testtoy.exe We like to think that: ..08 overshifting is okay but '(1<<bits_per_int)==0' is false. ..09a minus shifts backwards but '(t=-1,(15<<t)==7)' is false. ..14 i++ is structly left to right but '(i=0,a[i++]=i,a[0]==1)' is false. ..15 structs are packed but 'sizeof(char_int)==(sizeof(char)+sizeof(int))' is false. ..19-3 int<long but 'sizeof(int)<sizeof(long)' is false. ..22 floating point is always IEEE but 'STDC_IEC_559_is_defined' is false. From what I can say with my puny test cases, you are 78% mainstream 

Via Codepad.org ( C++: g++ 4.1.2 flags: -O -std=c++98 -pedantic-errors -Wfatal-errors -Werror -Wall -Wextra -Wno-missing-field-initializers -Wwrite-strings -Wno-deprecated -Wno-unused -Wno-non-virtual-dtor -Wno-variadic-macros -fmessage-length=0 -ftemplate-depth-128 -fno-merge-constants -fno-nonansi-builtins -fno-gnu-keywords -fno-elide-constructors -fstrict-aliasing -fstack-protector-all -Winvalid-pch ) .

Note that Codepad did not have stddef.h . I removed test 9 due to codepad using warnings as errors. I also renamed the count variable since it was already defined for some reason.

 We like to think that: ..08 overshifting is okay but '(1<<bits_per_int)==0' is false. ..14 i++ is structly left to right but '(i=0,a[i++]=i,a[0]==1)' is false. ..15 structs are packed but 'sizeof(char_int)==(sizeof(char)+sizeof(int))' is false. ..19-3 int<long but 'sizeof(int)<sizeof(long)' is false. From what I can say with my puny test cases, you are 84% mainstream 

How about right-shifting by excessive amounts–is that allowed by the standard, or worth testing?

Does Standard C specify the behavior of the following program:

void print_string(char *st)
 {
  char ch;
  while((ch = *st++) != 0)
    putch(ch); /* Assume this is defined */
 }
int main(void)
 {
  print_string("Hello");
   वापसी 0;
 }

On at least one compiler I use, that code will fail unless the argument to print_string is a "char const *". Does the standard permit such a restriction?

Some systems allow one to produce pointers to unaligned 'int's and others don't. Might be worth testing.

FYI, For those who have to translate their C skills to Java, here are a few gotchas.

 EXPECT("03 a char is 8 bits",CHAR_BIT==8); EXPECT("04 a char is signed",CHAR_MIN==SCHAR_MIN); 

In Java, char is 16-bit and signed. byte is 8-bit and signed.

 /* not true for Windows-64 */ EXPECT("05a long has at least the size of pointers",sizeof(long)>=sizeof(void*)); 

long is always 64-bit, references can be 32-bit or 64-bit (if you have more than an app with more than 32 GB) 64-bit JVMs typically use 32-bit references.

 EXPECT("08 overshifting is okay",(1<<bits_per_int)==0); EXPECT("09 overshifting is *always* okay",(1<<BITS_PER_INT)==0); 

The shift is masked so that i << 64 == i == i << -64, i << 63 == i << -1

 EXPECT("13 The smallest bits always come first",(t=0x1234,0x34==*(char*)&t)); 

ByteOrder.nativeOrder() can be BIG_ENDIAN or LITTLE_ENDIAN

 EXPECT("14 i++ is strictly left to right",(i=0,a[i++]=i,a[0]==1)); 

i = i++ never changes i

 /* suggested by David Thornley */ EXPECT("17 size_t is unsigned int",sizeof(size_t)==sizeof(unsigned int)); 

The size of collections and arrays is always 32-bit regardless of whether the JVM is 32-bit or 64-bit.

 EXPECT("19-1 char<short",sizeof(char)<sizeof(short)); EXPECT("19-2 short<int",sizeof(short)<sizeof(int)); EXPECT("19-3 int<long",sizeof(int)<sizeof(long)); 

char is 16-bit, short is 16-bit, int is 32-bit and long is 64-bit.