基础字符集是否仅依赖于C实现?

许多文本都警告将char值作为整数处理是不可移植的,例如假设’A’的值是65(如ASCII)。

但是什么决定了这个字符集是ASCII(或扩展forms)还是其他一些字符集? 它是由操作系统还是编译器决定的? 我假设这不依赖于硬件。

例如,英特尔PC是否可以使用EBCDIC等字符集(理论上)? 并且可以在Linux / Unix中更改LANG环境变量来更改C程序的基本字符集的值(如果再重新编译)?

(编辑:我现在看到Linux中的各种非拉丁字符集都具有相同的基本ASCII代码,例如KOI8-U – 我假设有些字符集与ASCII不兼容的变体)

标准并不关心任何这些细节,只要它关注的是只有“实施”。

在实践中,硬件和操作系统都可以指定预期使用该平台上的C实现的实现细节,或者如果他们想要与系统function互操作则需要使用它们(也就是说,提供的代码)与操作系统或硬件)。 所以我们经常说“在Win32上, sizeof(void*) == 4 ”。 但这是一个简写,因为有人可以 ,如果他们选择的话,编写一个在32位Windows上运行并具有不同指针大小的C实现。 我们真正的意思是,“在Win32 ABI中, sizeof(void*) == 4 ,并且在Win32上运行的不遵循Win32 ABI的C实现被排除在考虑之外”。

因此,实现可以做任何他们喜欢的事情,只要他们不介意他们是否可以(例如)使用遵循系统约定的dll。 可以定义字符集,但编译器和标准库的编写者喜欢,仅受标准中的内容限制。

也就是说,字符文字的值是编译时常量。 这告诉您基本执行字符集在运行时不能更改。

此外,如果它依赖于环境变量,那么确保程序以与编译时相同的值运行是有责任的。 这对用户来说非常不友好,但标准实际上并没有禁止某人编写C实现,对程序的运行方式有特殊的限制。

C标准说:

C99中的§5.2.1/ 1

应定义两组字符及其关联的整理顺序:写入源文件的集合(源字符集),以及在执行环境(执行字符集)中解释的集合。 每个集合进一步划分为基本字符集,其内容由本子条款给出,以及一组零个或多个特定于语言环境的成员(不是基本字符集的成员),称为扩展字符。 组合集也称为扩展字符集。 执行字符集的成员值是实现定义的

在启动时,编译器必须使用C语言环境,它只会在setlocale(LC_ALL, "");时获取操作系统的语言环境setlocale(LC_ALL, ""); 叫做。

编译器清楚地确定使用哪个源和执行字符集,因为可以进行交叉编译(例如,编译在使用ASCII的Linux机箱上使用EBCDIC的IBM大型机的代码)。