MinGW编译时std::locale构造函数抛异常,求解决方案
以下代码在MSVC 2022中可正常运行,但使用MinGW(x86_64-w64-mingw32 gcc-12.2.0)编译运行时抛出运行时错误:
#include <locale> int main() { std::locale l("en_US.utf8"); }
错误信息如下:
terminate called after throwing an instance of 'std::runtime_error' what(): locale::facet::_S_create_c_locale name not valid
尝试过""、"en_US"、"English"等区域设置名称,这些在MSVC中均可正常工作,但在MinGW下全部失败,仅"C"和"POSIX"能生效("C.utf8"等变体也不可用)。疑问:MinGW不是应该使用MSVC运行时吗?如何解决该问题?
MinGW的C++标准库差异:虽然MinGW依赖MSVC的C运行时(
CRT),但它使用的是GNUlibstdc++作为C++标准库,而非MSVC的MSVCPRT。libstdc++的locale实现并未直接调用MSVC CRT的locale接口,而是采用类Unix风格的locale命名规则,但Windows系统本身不提供这类locale支持,因此会出现名称无效的错误。使用Windows原生locale名称
Windows的locale命名格式与类Unix系统不同,需采用符合Windows规范的名称,例如:std::locale l("English_US"); // 对应英文(美国)区域设置也可使用
"en-US"这类语言+地区的缩写格式,部分MinGW版本可能需要使用"English_United States"这类完整名称,可通过Windows系统的区域设置列表确认可用名称。切换到MinGW-w64 ucrt64工具链
较新的MinGW-w64 ucrt64工具链采用UCRT(通用C运行时),对locale的处理更贴近Windows系统,同时兼容部分类Unix风格的locale名称。如果使用ucrt64版本的MinGW,尝试"en_US.UTF-8"(注意UTF-8大写)可能可以正常运行。避免指定具体locale名称
若无需特定locale,可直接使用默认构造的std::locale(),它会自动适配系统当前默认locale;或使用std::locale::classic()获取标准C locale,该方式在所有平台上都能稳定工作。
内容的提问来源于stack exchange,提问作者n.m.is-an-unemployed-ai-agent

