Мало того, что завершение каждого вызова setlocale
, возможно, слишком медленно. Это совершенно поточно-небезопасно и, следовательно, небезопасно для использования в общем / библиотечном коде.
Если вы работаете в POSIX или POSIX-подобной системе, вам нужно newlocale
/ uselocale
. Выполните следующее (что может быть медленным) один раз и сохраните результат:
locale_t safe_locale = newlocale(LC_NUMERIC_MASK, "C", duplocale(LC_GLOBAL_LOCALE));
Тогда, когда вы захотите использовать:
locale_t old = uselocale(safe_locale);
/* Do stuff with it. */
uselocale(old);
Вам не нужно переключаться вперед и назад вокруг каждой операции, только перед тем, как вернуться к вызывающему абоненту, который может ожидать, что его языковой стандарт не будет нарушен, но в любом случае он не должен медленно переключаться назад и вперед, как это.
В качестве альтернативы, просто не учитывайте LC_NUMERIC
в вашем приложении. После вызова setlocale(LC_ALL, "")
, чтобы установить языковой стандарт в соответствии с настройками пользователя, позвоните setlocale(LC_NUMERIC, "C")
и оставьте все как есть. Это недопустимо / неприемлемо в библиотечном коде, но если вы пишете библиотечный код, вы можете решить и позволить вызывающей стороне взять на себя ответственность за любой подход, который он сочтет подходящим (никогда не соблюдая LC_NUMERIC
вообще, или используя newlocale
/ uselocale
для переключения). Вы можете либо просто записать это требование в документацию к его контракту, и трактовать несоблюдение контракта как неопределенное, либо вы можете активно проверять точку, отличную от '.'
, утверждая, что localeconv()->decimal_point
указывает на строку "."
(и возвращает ошибку или прерывает работу, если она не удерживается).