2015-07-16 4 views
14

मैं इस सरल डेमो द्वारा समस्या को पुन:जी ++ बग? (Bool_val 0: 1) रिटर्न न 0 और न ही 1

// bool_test_func.cpp 
#include <stdio.h> 

void func(bool* b) { 
    int a = (*b ? 0 : 1); 
    printf("%d\n", a); // EXPECT ether 0 or 1 here 
} 

// bool_test.cpp 
void func(bool* b); 

int main() { 
    int n = 128; 
    func((bool*)&n); 
    return 0; 
} 

-O0 संकलन और चलाएँ:

g++ -g -O0 -Wall -o bool_test bool_test.cpp bool_test_func.cpp 
[email protected]:~/testing/c++$ ./bool_test 
0 

-O1 संकलन और चलाने (अप्रत्याशित परिणाम):

g++ -g -O1 -Wall -o bool_test bool_test.cpp bool_test_func.cpp 
[email protected]:~/testing/c++$ ./bool_test 
129 

जब मैं -O2 एएसएम कोड की जांच, मुझे लगता है कि यह एक छ ++ बग, है जी ++ के optimzation कोड हमेशा लगता है bool मूल्य ईथर 1 या 0 है:

 

    00000000004005e6 : 
     4005e6:  48 83 ec 08    sub $0x8,%rsp 
     4005ea:  0f b6 37    movzbl (%rdi),%esi 
     4005ed:  83 f6 01    xor $0x1,%esi #just XOR the bool val 
     4005f0:  40 0f b6 f6    movzbl %sil,%esi 
     4005f4:  bf 94 06 40 00   mov $0x400694,%edi 
     4005f9:  b8 00 00 00 00   mov $0x0,%eax 
     4005fe:  e8 9d fe ff ff   callq 4004a0 
     400603:  48 83 c4 08    add $0x8,%rsp 
     400607:  c3      retq 
     400608:  0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1) 
     40060f:  00 

जीसीसी संस्करण 4.9.2 (Debian 4.9.2-10)

इस छ ++ डिजाइन द्वारा व्यवहार है? मैं इस गलत अनुकूलन को कैसे अक्षम कर सकता हूं? धन्यवाद ~

+0

जीसीसी संस्करण 4.9.2 (डेबियन 4.9.2-10) – mikewei

+5

दिलचस्प '# शामिल'। – erip

+12

अनुकूलन गलत नहीं है: एक बूल में केवल 0 या 1 हो सकता है। आप जो भी गुजर रहे हैं वह 'int' टाइप-दंड 'बूल' के रूप में दंडित है, अपरिभाषित व्यवहार ensues। – Quentin

उत्तर

49

मुझे लगता है कि यह एक g ++ बग है।

सम्मानपूर्वक असहमत होना चाहिए।

मैं इस गलत अनुकूलन को कैसे अक्षम कर सकता हूं?

यहां तक ​​कि अगर कि संभव है, यह नहीं है वास्तव में गलत :-)

आप (अंतर्निहित आइटम bool प्रकार की नहीं है) एक bool सूचक के रूप में एक गैर bool सूचक गुजर रहे हैं और मुझे पूरा यकीन है कि यह (पनिंग प्रकार के रूप में जाना जाता है) अपरिभाषित व्यवहार का आह्वान करता है।

इसलिए कोड जो कुछ भी चाहता है उसे करने के लिए स्वतंत्र है।

आप एक अनुबंध आप करने के लिए सहमत ही कभी bool मूल्यों के संकेत के रूप में पारित करने के लिए प्रोटोटाइप void func(bool* b) के बारे में सोच सकते हैं। यदि आप उस अनुबंध का उल्लंघन करते हैं, तो सभी दांव बंद हैं। इस विशेष मामले में, अपने कोड:

int a = (*b ? 0 : 1); 

0. 1 और सच करने के लिए झूठी कन्वर्ट करने के लिए आप वैध इनपुट (false/0 या true/1) की आपूर्ति के लिए थे, तो यह कह रहा है, xor input, 1 होगा बिल्कुल करने के लिए सही चीज़।

हालांकि, क्योंकि आप इसे 128 दे रहे हैं, xor परिणाम 129 में परिणाम।

+0

सहमत हुए। कार्यान्वयन मूल्य 0 और 1 के साथ एक बूल को लागू करने के लिए प्रतीत होता है। इसलिए जब तक बूल प्रकारों का उपयोग कभी भी किया जाता है, तो उन्हें आसानी से xor के साथ छेड़छाड़ की जा सकती है। Int में रूपांतरण भी आसान है, क्योंकि अंतर्निहित बूल एक int प्रतीत होता है, इसलिए कोई रूपांतरण ऑपरेशन आवश्यक नहीं है। – djgandy

+5

इसे टाइप पनिंग कहा जाता है, और मानक प्रतिबंधों को int से bool (333.10/10 में N3376) से दंडित किया जाता है। यह वास्तव में यूबी है। –

+0

प्रश्न का अंतिम भाग अनुकूलन को अक्षम करने का तरीका है। जबकि मैं दृढ़ता से ऐसा करने के खिलाफ सलाह देता हूं और "गलत अनुकूलन" के रूप में प्रश्नकर्ता के विवरण से असहमत हूं, वहां नामित ऑप्टिमाइज़ेशन हैं जिन्हें जीसीसी मानक के अनुसार यूबी में कोड लिखने के लिए अक्षम करने की अनुमति देता है। '-फनो-डिलीट-नल-पॉइंटर-चेक' एक प्रसिद्ध उदाहरण है। मैंने चेक नहीं किया है, लेकिन इस कोड को 'फिक्स-सख्त-एलियासिंग' ठीक करता है? –

संबंधित मुद्दे