C程序在启动时会继承其语言环境变量。这会自动发生。但是,这些变量不会自动控制库函数使用的语言环境,因为ANSI C表示默认情况下所有程序都在标准
"C"
语言环境中启动。
我有read that a C program must have the C locale when started,因此C程序在启动时必须执行以下操作:
setlocale(LC_ALL, "C");
但是这行代码如何在C程序中结束?编译器是否为我添加了它?
答案 0 :(得分:4)
编译器不会修改源代码并向主程序添加对setlocale()
的显式调用。相反,需要实现(编译器和库的组合)以确保程序的行为“好像”在开始时调用setlocale()
。
程序行为还有许多其他方面,实现也必须确保正常工作。例如,它必须确保stdin
,stdout
和stderr
设置正确 - 您不必在main()
程序中明确打开这些流,因为库确保在调用main()
之前设置它们。在POSIX系统上,启动代码确保正确设置environ
全局变量。您可以在execve()
的POSIX规范中看到许多相关信息,包括:
对于新的过程映像,相当于:
setlocale(LC_ALL, "C")
应在启动时执行。
C标准也说了同样的事情C11 §7.11.1.1 The setlocale
function说:
在程序启动时,相当于
setlocale(LC_ALL, "C");
已执行。
具体实现如何实现效果的细节本质上是特定于实现的,但通常通过使用适当的正确值初始化选定的全局变量来实现。该标准没有说明实施必须如何达到效果;它只是说它必须实现它。
答案 1 :(得分:3)
这是特定于平台的。在GNU / Linux系统上,语言环境由glibc管理,glibc将设置存储在全局变量_nl_global_locale
中。要满足默认设置的要求,只需initialized with the values for C
:
struct __locale_struct _nl_global_locale attribute_hidden =
{
.__locales =
{
#define DEFINE_CATEGORY(category, category_name, items, a) \
[category] = &_nl_C_##category,
#include "categories.def"
#undef DEFINE_CATEGORY
},
.__names =
{
[LC_ALL] = _nl_C_name,
#define DEFINE_CATEGORY(category, category_name, items, a) \
[category] = _nl_C_name,
#include "categories.def"
#undef DEFINE_CATEGORY
},
.__ctype_b = (const unsigned short int *) _nl_C_LC_CTYPE_class + 128,
.__ctype_tolower = (const int *) _nl_C_LC_CTYPE_tolower + 128,
.__ctype_toupper = (const int *) _nl_C_LC_CTYPE_toupper + 128
};
由于所有设置都已通过此初始化指向C语言环境,因此无需实际调用setlocale(LC_ALL, "C");
。