簡體   English   中英

為什么 std::locale(“”).name() 在 clang 和 gcc 上給出不同的結果?

[英]Why does std::locale(“”).name() give different results on clang and gcc?

在我的機器(MacOS 10.14.x)上編譯和運行以下代碼會導致在 clang++ 上打印一個空字符串,並在 g++ 上引發運行時錯誤。 為什么?

#include <locale>
#include <iostream>


int main()
{
  std::cout << "User-preferred locale setting is " <<
    std::locale("").name().c_str() << '\n';

  return 0;
}
$ clang++ locale.cc
$ ./a.out 
User-preferred locale setting is 


$ g++-mp-8 locale.cc 
$ ./a.out 
terminate called after throwing an instance of 'std::runtime_error'
  what():  locale::facet::_S_create_c_locale name not valid
User-preferred locale setting is Abort trap: 6

$ clang++ --version
clang version 7.0.1 (tags/RELEASE_701/final)
Target: x86_64-apple-darwin18.7.0
Thread model: posix
InstalledDir: /opt/local/libexec/llvm-7.0/bin

$ g++-mp-8 --version
g++-mp-8 (MacPorts gcc8 8.3.0_0) 8.3.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

目前,我認為這不是 MacOS 問題,因為在 cppreference 上運行示例。com 也會產生不同的結果。

您可以自己嘗試不同的編譯器版本: https://en.cppreference.com/w/cpp/locale/locale/name

無論如何,它不會報告與以下內容相同的內容:

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

int main()
{
  std::cout << "User-preferred locale setting is "
            << setlocale(LC_ALL, "") << "\n";

  return 0;
}

它為兩個編譯器返回相同的結果(“en_US.UTF-8”)。

我錯過了什么?

差異可能來自 clang++ 使用libc++而 g++ 使用libstdc++的事實。 function std::locale()在其中任何一個中定義,並且實現不同。

您可以使用strace (如果可用)進行檢查,如下所示:

$ strace -e file ./a.out
...
open("/usr/lib/.../libstdc++.so.6", O_RDONLY|O_CLOEXEC) = 3
...

在此示例中,使用了libstdc++

你是對的“有效字符串參數值的集合是“C”、“”和任何實現定義的值......”但是如果您嘗試設置為未知的本地(可能由 local("" )) 它將引發運行時錯誤。

看一下libstdc++-v3/config/locale/gnu/c_locale.cc的源碼

locale::facet::_S_create_c_locale(__c_locale& __cloc, const char* __s, __c_locale __old)
{
    __cloc = __newlocale(1 << LC_ALL, __s, __old);
    if (!__cloc)
    {
        // This named locale is not supported by the underlying OS.
        __throw_runtime_error(__N("locale::facet::_S_create_c_locale name not valid"));
    }
}

__newlocale function 是罪魁禍首。 它的 C function 將處理傳遞給它的值的轉換。

在 MAC-OS 上,似乎libstdc++沒有正確處理 "" 值,甚至在很多語言環境中都存在大量問題。

它在 libstdc++(由 g++ 使用)中是一個眾所周知的問題。 您可以輕松地在多個地方找到它,錯誤報告 1錯誤報告 2示例 1 如您所見,目前 libstdc++ 僅支持“C”語言環境。

我說使用ICU :)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM