2015-12-07 5 views
9

यह कोड जीसीसी और क्लैंग के संस्करण (उबंटू ट्रस्टी) में ठीक काम करता था, और विन 7 में वीएम पर मिंगव के माध्यम से ... हाल ही में मैंने विली में अपग्रेड किया और लगातार यहां क्लैंग क्रैश के साथ बनाया गया।क्या यह सरल सी ++ प्रोग्राम <locale> का उपयोग कर सही है?

#include <iostream> 
#include <locale> 
#include <string> 

int main() { 
    std::cout << "The locale is '" << std::locale("").name() << "'" << std::endl; 
} 

कभी कभी अपनी एक निरर्थक शब्द स्ट्रिंग Aborted: Core dumped और कभी कभी अपने invalid free द्वारा पीछा किया।

$ ./a.out 
The locale is 'en_US.UTF-8QX�у�X�у����0�����P�����\�(��\�(��\�(��h��t�������������y���������ț�ԛ�������en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_UP����`�������������������������p�����������@��������������`�������������p��������������������@��@��@��`��������p������������0��P��p���qp��!en_US.UTF-8QЈ[�����\�(��\�(��\�(�����������@�� �����P�����0�����P�����\�(��\�(��\�(��Ȣ�Ԣ����������������(��4��@��L��en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8!�v[��������������@�� �����P�����0�����P�����\�(��\�(���(��h��t��������������������Ȥ�Ԥ�������en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8!��[�� ����[�������7����7��.,!!x�[��!��[��!�[��@�����������@�� �����P�����0�����P�����\�(��\�(��\�(��(��4��@��L��X��d��p��|������������n_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8ѻAborted (core dumped) 

$ ./a.out 
The locale is 'en_US.UTF-8QX\%�QX\%�Q�G�0H��H�PI��I�\:|�Q\D|�Q\>|�QhK�tK��K��K��K��K��Q�K��K��K��K��K��K�en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8en_US.UTF-8ѻ 
*** Error in `./a.out': free(): invalid pointer: 0x0000000000b04a98 *** 
Aborted (core dumped) 

(ऊपर दोनों कार्यक्रम outputs बहुत संक्षिप्त या गया वे इस सवाल में फिट नहीं होता।)

मैं भी उसके साथ एक invalid free on Coliru रूप में अच्छी तरह मिला है।

लेकिन यह बहुत cppreference पर उदाहरण कोड के समान है:

#include <iostream> 
#include <locale> 
#include <string> 

int main() 
{ 
    std::wcout << "User-preferred locale setting is " << std::locale("").name().c_str() << '\n'; 
    // on startup, the global locale is the "C" locale 
    std::wcout << 1000.01 << '\n'; 
    // replace the C++ global locale as well as the C locale with the user-preferred locale 
    std::locale::global(std::locale("")); 
    // use the new global locale for future wide character output 
    std::wcout.imbue(std::locale()); 
    // output the same number again 
    std::wcout << 1000.01 << '\n'; 
} 

वास्तव में है कि कोड crashes Coliru भी ...: facepalm:

More Coliru से समान कोड का crashes

क्या यह क्लैंग द्वारा उपयोग की जाने वाली सी ++ लाइब्रेरी में एक बग है, या यह कोड दोषपूर्ण है?

ध्यान दें: यदि आप <clocale> का उपयोग करते हैं तो यह क्रैश सी ++ एपीआई तक सीमित प्रतीत होता है, इसके बजाय चीजें ठीक काम करने लगती हैं, इसलिए यह सी ++ बाइंडिंग में कुछ मामूली समस्या हो सकती है?

setlocale का उपयोग कर विविधताएं: 123

+0

मुझे स्पष्ट रूप से एक बग की तरह दिखता है। क्या आपने क्लैंग मेलिंग सूची और/या इसे बग के रूप में रिपोर्ट करने पर विचार किया था? पूछने के लिए एक और उपयुक्त जगह की तरह लगता है ... –

+0

अगर क्लैंग, कंपाइलर, इस कोड को संकलित करता है, तो यह एक क्लैंग बग है, और इसकी सूचना दी जानी चाहिए। –

+0

@LightnessRacesinOrbit: हाँ मुझे लगता है कि यह अगला चरण –

उत्तर

6

इस तरह लग रहा है अपने basic_string, जो सी के लिए जरूरत थी में libstdC++ के ABI परिवर्तन के कारण होता है ++ 11 अनुरूपता। इस संक्रमण को प्रबंधित करने के लिए, जीसीसी ने abi_tag विशेषता को जोड़ा, जो कार्यों के उलझन वाले नाम को बदलता है ताकि नए और पुराने एबीआई के लिए कार्य को अलग किया जा सके, भले ही परिवर्तन अन्यथा उलझन वाले नाम को प्रभावित न करे (उदाहरण के लिए वापसी का प्रकार समारोह)।

जीसीसी emits a call to_ZNKSt6locale4nameB5cxx11Ev पर यह कोड

#include <locale> 
#include <string> 

int main() { 
    std::locale().name(); 
} 

, जो std::locale::name[abi:cxx11]() const को demangles, और नए ABI के साथ एक एसएसओ स्ट्रिंग देता है।

बजना, अन्य दूसरी ओर, doesn't support the abi_tag attribute, और emits a call to_ZNKSt6locale4nameEv, जो demangles बस std::locale::name() const करने पर - एक गाय स्ट्रिंग (पुराने एबीआई) लौटने संस्करण है।

शुद्ध परिणाम यह है कि प्रोग्राम क्लैंग के साथ संकलित होने पर एक एसएसओ स्ट्रिंग के रूप में गाय स्ट्रिंग का उपयोग करने का प्रयास कर रहा है। हावोक ensues।

स्पष्ट कार्यवाही पुराने एबीआई को -D_GLIBCXX_USE_CXX11_ABI=0 के माध्यम से मजबूर करना है।

+0

वाह, यह कुछ अच्छा सुस्त है! यह मेरी मशीन और कोलिरु पर इसे ठीक करता है: http://coliru.stacked-crooked.com/a/b08f590618a7398a, http://coliru.stacked-crooked.com/a/0c769ee07e51fb02 –

1

मुझे लगता है कि "" पैरामीटर कुछ भ्रष्ट हो सकता है। मुझे नहीं लगता कि यह एक कानूनी तर्क है?

यह और कुछ नहीं है सत्यापित करने के लिए, कोशिश यह चल रहा है:

#include <iostream> 
#include <locale> 

int main() { 
    std::locale("").name(); 
} 
+0

यह एक टिप्पणी होना चाहिए। –

1

यह कम्पाइल और जीसीसी के साथ ठीक चलाता है:

g++ -Wall -pedantic locale.cpp 
    <= No errorrs, no warnings 

./a.out 
The locale is 'en_US.UTF-8' 
    <= Expected output 

परिशिष्ट:

बिल्कुल MSVS 2013 के साथ ही - कोई त्रुटि या चेतावनियां संकलित नहीं; कोई त्रुटि चल:

locale.cpp =>

#include <iostream> 
#include <locale> 
#include <string> 

int main() { 
    std::cout << "The locale is '" << std::locale("").name() << "'" << std::endl; 
} 

आउटपुट =>

locale 
The locale is 'English_United States.1252' 
संबंधित मुद्दे