2015-12-07 17 views
9

Bu kod gcc ve clang'ın (ubuntu trusty) sürümlerinde ve mingw üzerinden bir VM'de Win 7'de işe yaramış görünüyordu ... Son zamanlarda Wily'e geçtim ve sürekli olarak burada clang çökmesiyle geliştirdim.<locale> kullanarak bu basit C++ programı doğru mu?

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

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

Bazen onun anlamsız dize bazen Aborted: Core dumped ve invalid free onun ardından.

$ ./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) 

(büyük ölçüde kısaltılmış veya edildi Hem program çıkışları yukarıda onlar bu soruya uygun olmaz.)

Ben aynı zamanda onunla bir invalid free on Coliru aldık.

Ama bu cppreference taraftaki örnek koduna çok benzer:

#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'; 
} 

Aslında bu kodu da crashes Coliru ...: facepalm: Coliru benzer kod

Morecrashes.

Bu, C++ tarafından kullanılan C++ kütüphanesinde bir hata mı, yoksa bu kod bozuk mu?

Not: Ayrıca, bu çökmeler C++ api ile sınırlı gibi görünüyor, <clocale> kullanırsanız, işler iyi çalışıyor gibi görünüyor, bu nedenle bu yalnızca C++ bağlamaları üzerinde önemsiz bir sorun olabilir? setlocale kullanarak

Varyasyonlar: 123

+0

Bana açıkça bir hata gibi görünüyor. Clang mail listesini sormayı ve/veya bir hata olarak rapor etmeyi düşündünüz mü? Sormak için daha uygun bir yer gibi görünüyor ... –

+0

Eğer clang, derleyici, bu kodu derlediğinde çöküyorsa, o zaman bu bir clang hatasıdır ve rapor edilmelidir. –

+0

@LightnessRacesinOrbit: Evet, sonraki adım –

cevap

6

bu Görünüşe

locale.cpp =>

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

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

Çıktı C için gerekli olduğunu onun basic_string, içinde libstdC++ 'ın ABI değişiklik kaynaklanır ++ 11 uyumluluk. Bu geçişi yönetmek için GCC, işlevlerin karışık ismini değiştiren abi_tag özniteliğini ekledi; böylece değişiklik, aksi taktirde değişmiş adı etkilemese bile yeni ve eski ABI işlevleri ayırt edilebilir. fonksiyonu).

std::locale::name[abi:cxx11]() const için demangles ve yeni ABI'lı bir TOA dize döndürür GCC emits a call to_ZNKSt6locale4nameB5cxx11Ev üzerindeki bu kod

#include <locale> 
#include <string> 

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

.

Clang, basitçe std::locale::name() const demangles diğer Öte yandan, doesn't support the abi_tag attribute ve emits a call to_ZNKSt6locale4nameEv, üzerinde - bir İNEK dize (eski ABI) dönen sürümüdür.

Net sonuç, programın Clang ile derlendiğinde SSO dizesi olarak bir COW dizesi kullanmaya çalıştığı sonucudur. Tahriş devam ediyor.

Açık olan geçici çözüm, eski ABI'yı -D_GLIBCXX_USE_CXX11_ABI=0 aracılığıyla zorlamaktır.

+0

vay, bu çok hoş bir hilkat! Bu, makinemde ve coliru'da düzeltir: http://coliru.stacked-crooked.com/a/b08f590618a7398a, http://coliru.stacked-crooked.com/a/0c769ee07e51fb02 –

1

Ben "" parametre şey bozulmasını olabileceğini düşünüyorum. Bence yasal bir tartışma değil mi?

bu başka bir şey değil doğrulamak için, deneyin bu çalışan:

hazırlar ve GCC ile sadece iyi çalışır
#include <iostream> 
#include <locale> 

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

Bu bir yorum olmalı. –

1

:

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

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

EK:

Tam

MSVS 2013 ile aynı - derleme hatası veya uyarı yok; Hata çalışan: =>

locale 
The locale is 'English_United States.1252'