यहाँ मेरा कोड है:
#include <string.h>
#include <stdio.h>
typedef char BUF[8];
typedef struct
{
BUF b[23];
} S;
S s;
int main()
{
int n;
memcpy(&s, "1234567812345678", 17);
n = strlen((char *)&s.b) / sizeof(BUF);
printf("%d\n", n);
n = strlen((char *)&s) / sizeof(BUF);
printf("%d\n", n);
}
किसी भी अनुकूलन स्तर के साथ gcc 8.3.0 या 8.2.1 का उपयोग करना -O0
, 0 2
जब मैं उम्मीद कर रहा था तो यह आउटपुट करता है 2 2
। संकलक ने तय किया कि यह करने के strlen
लिए बाध्य है b[0]
और इसलिए विभाजित होने वाले मूल्य के बराबर या उससे अधिक कभी नहीं हो सकता है।
क्या यह मेरे कोड में बग है या कंपाइलर में बग है?
यह मानक में स्पष्ट रूप से नहीं लिखा गया है, लेकिन मुझे लगा कि सूचक सिद्धता की मुख्य धारा की व्याख्या यह थी कि किसी भी वस्तु के लिए X
, कोड (char *)&X
को एक सूचक उत्पन्न करना चाहिए जो पूरे पर पुनरावृति कर सकता है X
- इस अवधारणा को धारण करना चाहिए भले ही X
ऐसा हो आंतरिक संरचना के रूप में उप-सरणियाँ।
(बोनस प्रश्न, क्या इस विशिष्ट अनुकूलन को बंद करने के लिए एक gcc ध्वज है?)
2 2
विभिन्न विकल्पों के तहत मेरी जीसीसी 7.4.0 रिपोर्ट ।
s.b
तक ही सीमित है b[0]
यह 8 वर्ण, और इसलिए दो विकल्प तक ही सीमित है: (1) के बाहर के लिए बाध्य मामले में पहुँच वहाँ 8 में गैर-शून्य वर्ण, जो यूबी है कर रहे हैं, (2) वहाँ एक अशक्त चरित्र जो में है, लेन 8 से कम है, इसलिए 8 से भाग देना शून्य देता है। इसलिए एक साथ (1) + (2) संकलक दोनों मामलों में समान परिणाम देने के लिए UB का उपयोग कर सकते हैं