Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have the following code suggested for a previous question of mine generate range for which std::isalpha evaluates to true . It displays all chars in the current locale for which isalpha evaluates to true, so for an english locale it displays AB...Zab...z. However, I am getting a Segmentation fault: 11 on the line if(table[i] & ctype::alpha) when trying to access table. I compiled it with both g++4.9 and clang++ (Apple LLVM version 5.1 (clang-503.0.40) ), on OS X Mavericks 10.9.4. On all other platforms (Linux/Solaris) it works, no segmentation faults.

Can anyone point out if there is something broken in the C++'s libc++/libstdc++ on OS X, or at least if the problem is reproducible?

#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: after many hours I found out (following Howard's suggestion) that clang++ was picking up by default libstdc++ (why I have yet to find out), which seem to be broken in terms of locale support. When compiling with libc++, the program works as it is supposed to.

like image 899
vsoftco Avatar asked Aug 05 '14 03:08

vsoftco


2 Answers

Might as well turn my comments into an answer:

As libstdc++ does not support anything but the 'generic' locale model on OSX, C++ locales are hardly supported at all. Your segfault is caused by facet.table(); returning a null pointer (this is not actually allowed by the standard).

Sadly the only solution for now is to stay away from locales on OSX altogether, or switch to libc++ instead which as @HowardHinnant points out works fine.

like image 161
user657267 Avatar answered Nov 06 '22 19:11

user657267


I'm using clang++ (Apple LLVM version 5.1 (clang-503.0.40) ), on OS X Mavericks 10.9.4, and your program works fine for me. I added:

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

and both asserts pass. Compiled with:

clang++ test.cpp
like image 23
Howard Hinnant Avatar answered Nov 06 '22 17:11

Howard Hinnant