OS X上的std::locale段错误,不能在任何其他平台上重现

std::locale segfault on OS X, cannot reproduce on any other platform

本文关键字:任何 不能 其他 平台 错误 std 上的 locale 段错误 OS      更新时间:2023-10-16

对于我之前的一个问题,我建议使用以下代码生成std::isalpha求值为true的范围。它显示当前语言环境中isalpha求值为true的所有char,因此对于英语语言环境,它显示AB...Zab...z。然而,当试图访问table时,我在if(table[i] & ctype::alpha)线上获得Segmentation fault: 11。我在OS X Mavericks 10.9.4上使用g++4.9和clang++ (Apple LLVM version 5.1 (clang-503.0.40))编译它。在所有其他平台上(Linux/Solaris),它工作,没有分割错误。

有没有人可以指出,如果有什么东西在c++的libc++/libstdc++在OS X上,或者至少如果问题是可重复的?

#include <iostream>
#include <locale>
int main() {
    typedef std::ctype<char> ctype;
    std::locale locale;
    const ctype& facet = std::use_facet<ctype>(locale);
    const ctype::mask* table = facet.table();
    // You might skip this and work with the table, only.
    std::string result;
    for(unsigned i = 0; i < facet.table_size; ++i) {
        if(table[i] & ctype::alpha)
            result += char(i);
    }
    std::cout << result << 'n';
    return 0;
}

PS:几个小时后,我发现(按照Howard的建议)clang++默认使用libstdc++(为什么我还没有发现),这似乎在语言环境支持方面被打破了。当使用libc++编译时,程序按照预期工作。

不妨把我的评论变成一个答案:

由于libstdc++不支持OSX上的"通用"区域设置模型,因此几乎不支持c++区域设置。你的段错误是由facet.table();返回一个空指针引起的(这实际上是不允许的标准)。

遗憾的是,目前唯一的解决方案是完全远离OSX上的区域设置,或者切换到libc++,正如@HowardHinnant指出的那样工作得很好。

我在OS X Mavericks 10.9.4上使用clang++ (Apple LLVM version 5.1 (clang-503.0.40)),您的程序对我来说工作得很好。我说:

assert(table != nullptr);
assert(table == facet.classic_table());

和两个断言都通过。编译:

clang++ test.cpp
相关文章: