Skip to content

Instantly share code, notes, and snippets.

@akinomyoga
Last active March 12, 2017 00:26
Show Gist options
  • Save akinomyoga/18185db4ac1dcf9b6dfd518571ab25a6 to your computer and use it in GitHub Desktop.
Save akinomyoga/18185db4ac1dcf9b6dfd518571ab25a6 to your computer and use it in GitHub Desktop.
Cygwin 2.7.0 std::locale/std::codecvt (cygstdc++-6.dll) の問題と duplocale (cygwin1.dll) の問題 → 解決法 https://github.com/akinomyoga/cyglocale_patcher
#include <stdlib.h>
#include <locale.h>
// Cygwin で duplocale で作ったロケールを uselocale に渡して
// MB_CUR_MAX を参照するとクラッシュする。
//
// Note: MB_CUR_MAX は __locale_mb_cur_max() に展開される。
// Note: newlocale で作成したロケールを直接使った場合は問題ない。
// Note: duplocale の代わりに newlocale(0, "C", loc) を使った場合も問題ない。
int main() {
locale_t const loc = newlocale(1 << LC_ALL, "", NULL);
locale_t const dup = duplocale(loc);
locale_t const old = uselocale(dup);
int const ret = MB_CUR_MAX; // ここで突然死
uselocale(old);
return ret;
}
//
// なんと cygwin では std::locale("") しただけでエラーになる。
// (一方で VC なら大丈夫だった。)
//
// ```cpp:test.cpp
#include <locale>
int main() {
std::locale("");
return 0;
}
// ```
//
// ```sh
// $ g++ -std=c++14 -o test.exe test.cpp
// $ ./test.exe
// terminate called after throwing an instance of 'std::runtime_error'
// what(): locale::facet::_S_create_c_locale name not valid
// ```
//
// "" は valid な引数 (C++14 §22.3.1.2/6) なので、
// std::runtime_error は起こらない (C++14 §22.3.1.2/5) はずである。
// これでは locale-specific native environment (C11 7.11.1.1/3) の
// std::locale オブジェクトが作れない…。
//
// → https://github.com/akinomyoga/cyglocale_patcher に移動しました
#include <locale>
#include <iostream>
int main() {
#ifdef USE_PATCH_DLL
int use_libstdcxx_locale_patch();
use_libstdcxx_locale_patch();
#endif
std::ios_base::sync_with_stdio(false);
std::wcout.imbue(std::locale(""));
std::wcout << L"あいうえお1" << std::endl;
std::wcout.imbue(std::locale("ja_JP.UTF-8"));
std::wcout << L"あいうえお2" << std::endl;
std::wcout.imbue(std::locale("ja_JP.cp932"));
std::wcout << L"あいうえお3" << std::endl;
std::wcout.imbue(std::locale("ja_JP.EUC-JP"));
std::wcout << L"あいうえお4" << std::endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment