2015-12-07 4 views
9

Dieser Code schien in (ubuntu trusty) Versionen von gcc und clang in Ordnung zu sein, und in Win 7 auf einer VM via mingw ... Kürzlich habe ich auf Wily und Builds mit Clang Crash konsequent hier aktualisiert.Ist dieses einfache C++ Programm mit <locale> korrekt?

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

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

Manchmal ist es ein Kauderwelsch Zeichenfolge von Aborted: Core dumped gefolgt und manchmal seine 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) 

(Beide Programmausgaben oben stark abgekürzt wurden, oder sie würden in dieser Frage nicht passt.)

ich auch eine invalid free on Coliru damit auch bekam.

Aber das ist sehr ähnlich dem Beispiel-Code auf 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'; 
} 

Eigentlich dass Code crashes Coliru auch ...: facepalm:

Morecrashes ähnlichen Code aus Coliru.

Ist das ein Fehler in der C++ - Bibliothek, die von clang verwendet wird, oder ist dieser Code defekt?

Beachten Sie auch: Diese Abstürze scheinen auf C++ api beschränkt zu sein, wenn Sie stattdessen <clocale> verwenden scheinen die Dinge in Ordnung zu funktionieren, so kann es nur ein triviales Problem in den C++ - Bindungen sein?

Variationen setlocale mit: 123

+0

Sieht ziemlich offensichtlich wie ein Fehler für mich aus. Haben Sie darüber nachgedacht, die Claming-Mailingliste zu fragen und/oder als Bug zu melden? Scheint wie ein passender Ort zu fragen ... –

+0

Wenn call, der Compiler, kompiliert diesen Code, dann ist dies ein Clang Bug, und sollte gemeldet werden. –

+0

@LightnessRacesinOrbit: Ja, ich denke, das ist der nächste Schritt –

Antwort

6

wie folgt aussieht wird von libstdC++ 's ABI Änderung seiner basic_string verursacht, die für C benötigt wurde ++ 11 Übereinstimmung. Um diesen Übergang zu verwalten, hat GCC das Attribut abi_tag hinzugefügt, das den Namen der Funktionen ändert, so dass Funktionen für die neue und die alte ABI unterschieden werden können, auch wenn die Änderung den fehlenden Namen nicht beeinflussen würde (zB der Rückgabetyp von a Funktion).

Dieser Code

#include <locale> 
#include <string> 

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

auf GCC emits a call to_ZNKSt6locale4nameB5cxx11Ev, die std::locale::name[abi:cxx11]() const demangles und gibt einen SSO-String mit dem neuen ABI.

Clang, auf andere dagegen doesn't support the abi_tag attribute und emits a call to_ZNKSt6locale4nameEv, die einfach std::locale::name() const demangles - das ist die Version ist eine Kuh String zurückkehrt (das alte ABI).

Das Nettoergebnis ist, dass das Programm versucht, eine COW-Zeichenfolge als eine SSO-Zeichenfolge zu verwenden, wenn mit Clang kompiliert wird. Verwüstung folgt.

Die offensichtliche Problemumgehung besteht darin, den alten ABI über -D_GLIBCXX_USE_CXX11_ABI=0 zu erzwingen.

+0

Wow, das ist ein schönes Detektiv! Dies behebt es auf meinem Rechner und auf coliru: http://coliru.stacked-crooked.com/a/b08f590618a7398a, http://coliru.stacked-crooked.com/a/0c769ee07e51fb02 –

1

Ich denke, die "" Parameter etwas korrumpiert werden könnte. Ich denke nicht, dass es ein juristisches Argument ist?

es ist nichts anderes, um zu überprüfen, versuchen Sie dies ausgeführt wird:

#include <iostream> 
#include <locale> 

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

Dies sollte ein Kommentar sein. –

1

Es kompiliert und läuft mit GCC ganz gut:

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

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

NACHTRAG:

genau das gleiche mit MSVS 2013 - keine Fehler oder Warnungen kompilieren; keine Fehler laufen:

locale.cpp =>

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

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

Output =>

locale 
The locale is 'English_United States.1252'