2015-05-08 8 views
12

मैंने अपनी परियोजना पर -fsanitize=undefined पर स्विच किया जो कैच, इकाई परीक्षण पुस्तकालय का उपयोग करता है। कैच से एक पंक्ति को इस ध्वज द्वारा अपरिभाषित व्यवहार के कारण संकेत दिया गया था। मैं एक अलग उदाहरण बनाने में कामयाब रहे:क्या यह कोड वास्तव में अपरिभाषित है, क्योंकि क्लैंग इंगित करता है?

#include <iomanip> 
#include <sstream> 

int main() 
{ 
    std::ostringstream os; 
    os << "0x" << std::setfill('0') << std::hex; 
} 

साथ संकलित:

clang++ -fsanitize=undefined main.cpp 

अगर मैं इस चलाने के लिए, निम्न प्रिंट दिया जाता है:

/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/bits/ios_base.h:96:24: runtime error: load of value 4294967221, which is not a valid value for type 'std::_Ios_Fmtflags' 
/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/bits/ios_base.h:76:67: runtime error: load of value 4294967221, which is not a valid value for type 'std::_Ios_Fmtflags' 

यह बजना 3.6.0 पर मेरे लिए होता है और clang 3.4-1ubuntu3 के साथ एक दोस्त के लिए। यह मेरे लिए जीसीसी संस्करण 4.9.2

पर ऐसा नहीं होता है तो यहां क्या है? क्या यह कोड वास्तव में बुरा है, या क्या क्लैंग के अंत में कुछ ख़राब चल रहा है?

+1

बस 'ओएस << std :: हेक्स;' इस मुद्दे को पुन: उत्पन्न करने के लिए भी लगता है। – dyp

+0

http://stackoverflow.com/questions/20617788/using-memory-sanitizer-with-libstdc शायद यह? –

+0

मुझे एक और वर्णनात्मक शीर्षक पसंद आएगा लेकिन मुझे एक के साथ आने में मुश्किल हो रही है। –

उत्तर

12

यह एक bug in libstdc++ है, शीर्षक -fsanitize = अपरिभाषित और साझा पुस्तकालयों साथ cfe-dev मेलिंग सूची धागे से कहते हैं:

यह libstdc में एक बग है ++। एक बार सैनिटरी ब्लैकलिस्ट फ़ाइल के साथ आप इसके आसपास काम करने में सक्षम होंगे, एक बार विल के पैच के लिए पैच, लेकिन के लिए, मैन्युअल रूप से उन्हें फ़िल्टर करना आपके सबसे अच्छे विकल्प होने की संभावना है।

यहां इसे ठीक करने के लिए एक पैच है; मैं इसे अगले कुछ दिनों में libstdC++ अपस्ट्रीम पर धक्का दे रहा हूं। [...]

मैं टिप्पणी नहीं यह असामान्य नहीं है में DYP करने के लिए सिस्टम को देखने के लिए जहां clanglibstdc++ के रूप में करने का विरोध किया libc++ का उपयोग करता है और हम वास्तव में इस मुद्दे को दोबारा कर सकते हैं अगर हम -stdlib=libstdc++ के माध्यम से Coliru explicitly using libstdc++ पर यह परीक्षण बताया गया है।

निम्नलिखित libstdc++ बग रिपोर्ट: bad enum values computed by operator~ in ios_base.h इस मुद्दे को शामिल किया गया और कहते हैं:

अतिभारित ऑपरेटर ~ ios_base.h में enumerations के लिए परिभाषित रहा है निम्नलिखित रूप है:

Enum operator~(Enum e) { return Enum(~static_cast<int>(e)); } 

~ गणना प्रकार के मानों की सीमा के बाहर मूल्य बनाता है, इसलिए एनम प्रकार पर वापस कास्ट एक अनिर्दिष्ट मान है ( [expr.static.cast] p10 देखें), और व्यावहारिक रूप से यह pr एनम प्रकार के लिए प्रतिनिधित्व मूल्यों की सीमा के बाहर एक एनम मान oduces, तो व्यवहार अपरिभाषित है।

संदर्भ [expr.static.cast] p10 के लिए कहते हैं:

अभिन्न या गणना प्रकार का मान स्पष्ट रूप से गणना प्रकार में बदला जा सकता। मूल्य अपरिवर्तित है यदि मूल मान गणना मूल्यों (7.2) की सीमा के भीतर है। अन्यथा, परिणामी मान अनिर्दिष्ट है (और उस सीमा में नहीं हो सकता है)।फ़्लोटिंग-पॉइंट प्रकार का एक मूल्य को गणित प्रकार में भी परिवर्तित किया जा सकता है। परिणामस्वरूप मान मूल मान को अंतर्निहित गणना के प्रकार (4.9), और बाद में गणना प्रकार के रूप में परिवर्तित करने जैसा ही है।

और जैसा कि एचवीडी कहता है कि यह औपचारिक रूप से अनिर्दिष्ट व्यवहार है लेकिन रिचर्ड बताते हैं कि अभ्यास में अपरिभाषित व्यवहार समाप्त होता है।

टी.सी. बताते हैं इस DR 1766: Values outside the range of the values of an enumeration से अपरिभाषित व्यवहार करने के लिए अनिर्दिष्ट से बदला गया था:

हालांकि इस मुद्दे को स्पष्ट किया कि 1094 गणना प्रकार की अभिव्यक्ति का मूल्य गणना के मूल्यों की सीमा के भीतर गणना करने के लिए रूपांतरण के बाद नहीं हो सकता है टाइप करें (5.2.9 [expr.static.cast] अनुच्छेद 10 देखें), परिणाम केवल एक अनिर्दिष्ट मान है। यह अनिश्चित व्यवहार का उत्पादन करने के लिए शायद मजबूत किया जाना चाहिए, इस तथ्य के प्रकाश में कि अपरिभाषित व्यवहार अभिव्यक्ति को निरंतर बना देता है। यह भी देखें 9.6 [कक्षा.बीबी] अनुच्छेद 4.

नया शब्द N4431 में ड्राफ्ट मानक में दिखाई देता है।

+0

ओह दिलचस्प वास्तव में। उन्हें बहुत खराब फ़िल्टर करने से मैन्युअल रूप से ऐसी त्रुटियों को तोड़ने के लिए gdb का उपयोग करने की संभावना को हटा दिया जाता है ताकि उन्हें ठीक करने के लिए स्टैकट्रैक प्राप्त हो सके। – Tobias

+0

तथ्य यह है कि कलाकार एक अनिर्दिष्ट मूल्य उत्पन्न करता है इसका मतलब है कि व्यवहार * परिभाषित किया गया है। यदि व्यवहार अपरिभाषित होगा, मानक कहेंगे कि व्यवहार अपरिभाषित है। (हालांकि, यह अभी भी उपयोगी व्यवहार नहीं है, इसलिए कोड अभी भी बदला जाना चाहिए।) – hvd

+0

@ एचवीडी अच्छी तरह से रिचर्ड कहते हैं कि 'प्रैक्टिस में यह एनम प्रकार के लिए प्रतिनिधित्व मूल्यों की सीमा के बाहर एक एनम मूल्य उत्पन्न करता है, इसलिए व्यवहार अपरिभाषित है' जब तक सैनिटाइज़र इसे देखता है कि भेद उपलब्ध नहीं हो सकता है। –

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