是否存在 sizeof(char) != 1 或至少 CHAR_BIT > 8 的机器?

Posted

技术标签:

【中文标题】是否存在 sizeof(char) != 1 或至少 CHAR_BIT > 8 的机器?【英文标题】:Are there machines, where sizeof(char) != 1, or at least CHAR_BIT > 8? 【发布时间】:2011-01-13 23:59:37 【问题描述】:

是否有机器(或编译器),其中sizeof(char) != 1

C99 标准 是否规定在标准合规性实施中sizeof(char) 必须正好为 1?如果有,请给我章节号和引文。

更新: 如果我有一台机器(CPU),它不能寻址字节(最小读取是 4 个字节,对齐),但只有 4-s 字节(uint32_t),可以为这台机器编译器定义sizeof(char)到 4? sizeof(char) 将为 1,但 char 将有 32 位CHAR_BIT 宏)

更新2: 但是 sizeof 结果不是字节!它是 CHAR 的大小。而 char 可以是 2 字节,或者(可能是)7 位?

更新3: 好的。所有机器都有sizeof(char) == 1。但是哪些机器有CHAR_BIT > 8

【问题讨论】:

我担心 C99 标准合规性。我与 C99 编译器密切合作 随着 Unicode 变得更加重要,可能会出现使用 Unicode 字符作为 char(而不是 wchar)的非标准编译器。即使标准规定 sizeof(char) 必须为 1 ,我不会依赖这个假设。 没有 C 编译器 sizeof(char) 不是 1,unicode 与否。 @Chip: sizeof(char) 始终为 1,即使 char 是 32 位(在某些系统上会发生这种情况)。 C 有很多有趣的缺点。 所有版本的 C 标准都要求 CHAR_BIT 至少为 8;你不能有 CHAR_BIT == 7 并且符合标准。但是,对于机器来说,CHAR_BIT > 8 是完全可行的。我相信旧的 Cray 机器确实如此(sizeof(char) == sizeof(short) && sizeof(char) == sizeof(int) 在那些;我不记得是 sizeof(int) == sizeof(long) 还是 CHAR_BIT 是 32 还是 64;我希望它是 32 ,我也认为sizeof(long) == 1。(您可以找到Cray C manual 的参考,但不能在线访问)。 【参考方案1】:

在 C99 中始终为 1,第 6.5.3.4 节:

当应用于具有 输入 char、unsigned char 或 signed char,(或其合格版本) 结果是 1。

编辑:不是您问题的一部分,而是出于Harbison and Steele's. C: A Reference Manual, Third Edition, Prentice Hall, 1991 (pre c99) p 的兴趣。 148:

一个存储单元被认为是 一个占用的存储量 特点;对象的大小 类型 char 因此是 1。

编辑:在回答您更新的问题时,Harbison 和 Steele 的以下问答是相关的(同上,Ex. 4 of Ch. 6):

是否允许有一个C 实现类型char可以 表示范围从 -2,147,483,648 到 2,147,483,647?如果是这样,那将是什么sizeof(char) 在那个实施下?什么会 是最小和最大范围 输入int?

答案(同上,第 382 页):

允许(如果浪费) 实现使用 32 位 表示类型char。不管 实施,价值 sizeof(char) 始终为 1。

虽然这并没有具体解决这样一种情况,比如字节是 8 位,char 是其中的 4 个字节(在 c99 定义中实际上是不可能的,见下文),但 sizeof(char) = 1 总是从c99 标准以及 Harbison 和 Steele。

编辑:事实上(这是对您的 upd 2 问题的回应),就 c99 而言,sizeof(char) 以字节为单位,再次来自第 6.5.3.4 节:

sizeof 运算符产生大小 (以字节为单位)其操作数

因此结合上面的引用,8 位字节和 char 作为其中 4 个字节是不可能的:对于 c99,一个字节与 char 相同。

在回答您提到 7 位 char 的可能性时:这在 c99 中是不可能的。根据标准第 5.2.4.2.1 节,最小值为 8:

它们的实现定义的值应等于或更大 [我的重点]在幅度上与显示的值相同,符号相同。

——不是位域的最小对象的位数(字节)

 **CHAR_BIT 8**

— 有符号字符类型对象的最小值

**SCHAR_MIN -127//−(27−1)** 

—signed char 类型对象的最大值

**SCHAR_MAX +127//27−1** 

— unsigned char 类型对象的最大值

**UCHAR_MAX 255//28−1** 

——char 类型对象的最小值

**CHAR_MIN**    see below 

——char 类型对象的最大值

**CHAR_MAX**    see below

[...]

如果 char 类型的对象的值 被视为有符号整数时 在表达式中使用的值 CHAR_MIN 应与 SCHAR_MIN 和 CHAR_MAX 的值 应与 SCHAR_MAX。否则,值 CHAR_MIN 应为 0 且值为 CHAR_MAX 应与 UCHAR_MAX。值 UCHAR_MAX 应等于 2^CHAR_BIT - 1。

【讨论】:

如果您知道您正在使用 char 类型并且您知道该语言要求它们的大小为 1,那么为什么总是放置多余的 sizeof(char) 是个好主意?跨度> @Roger。当然,一般来说,使用sizeof 来实现独立性是非常重要的。是的,鉴于以上所有情况,char 有点例外,可以安全地假设sizeof(char)=1。我说“好主意”是因为:(a) 如果有人后来改用,例如long,它会降低出错的机会,因为sizeof(char) 用作提醒,(b) 代码阅读器,例如对sizeof(char) 不确定的OP 不会浪费时间担心代码是否正确,(c) 当前的非标准或未来的实现(不太可能)。无论如何,这就是我习惯的原因。 (a) 和 (c) 有更严重的后果,这无法解决,甚至无法解决;还有YAGNI。 (b) 中的某个人只需要被告知一次——我不需要在我的代码的每一行中都教他们。但是,使用sizeof(char) 也有缺点:这是另一个需要辩论/检查/等的项目。在您的编码约定/标准/指南中,浪费我的时间想知道您是否真的了解 C 以及其他可能不正确的内容,占用视觉/心理/文本行“带宽”。 @Ramashalanka:是的,编译后的代码是等价的。这是关于可读性以及人们如何使用我正在谈论的源代码的所有问题。 (FWIW,我认为您在这里有一个不错的 +1 答案,我只是发现“总是使用 sizeof(char)”是被误导的,对我来说是一个热键问题,即使是一个小问题。) @Ramashalanka:我想这是一个主观的事情。如果有些人真的想使用它,那很好,可以在其余时间一直使用它。但在我看来,这没有任何意义,因为如果你不能相信 sizeof(char) == 1 会保持不变,那么你就不能真正相信任何事情。【参考方案2】:

没有sizeof(char) 为 4 的机器。它总是 1 个字节。该字节可能包含 32 位,但就 C 编译器而言,它是一个字节。有关更多详细信息,我实际上将向您指出C++ FAQ 26.6。该链接很好地涵盖了它,我相当肯定 C++ 从 C 中获得了所有这些规则。您还可以查看 comp.lang.c FAQ 8.10 以获取大于 8 位的字符。

Upd2:但 sizeof 结果不是字节 !它是 CHAR 的大小。和 char 可以 是 2 字节,还是(可能是)7 位?

是的,它是字节。让我再说一遍。根据 C 编译器,sizeof(char) 是 1 个字节。人们俗称的字节(8 位)不一定与 C 编译器所称的字节相同。 C 字节中的位数取决于您的机器架构。它也保证至少为 8。

【讨论】:

拜托!!! C++ 是与 C (C99) 真正不同的语言。这个问题仅与普通 C 有关。 机器/CPU无法访问8位字节怎么办?禁止未对齐的访问。(即使在 x86 malloc 上也返回对齐的数据并以 4 字节的倍数分配内存。)然后 CHAT_BIT 将大于 8。是的,这样的平台可能相当特殊。 @osgx,当人们试图混合 C 和 C++ 时,我会像你刚才那样尖叫。但我认为在这种情况下,一个 C++ FAQ 条目同样适用于 C。 “8 位”的正确名称是八位字节。 C 标准使用“字节”一词来表示一个字符大小的对象。其他人可能以不同的方式使用“字节”一词,通常是指“八位字节”,但在 C(和 C++,或 Objective-C)中,它的意思是“字符大小的对象”。一个 char 可能超过 8 位,或超过一个八位字节,但它始终是一个字节。【参考方案3】:

PDP-10 和 PDP-11 是。

更新:没有用于 PDP-10 的 C99 编译器。

Analog Devices 32 位 SHARC DSP 的某些型号具有 CHAR_BIT=32,并且 TMS32F28xx 的德州仪器 DSP 具有 CHAR_BIT=16,reportedly。

更新:GCC 3.2 for PDP-10 CHAR_BIT=9 (检查该存档中的 include/limits.h)。

【讨论】:

不要将类似但非 C 语言的实现与 C 混淆。您甚至说“我担心 C99 标准合规性。我与 C99 编译器密切合作。” @Roger:称 GCC3 不符合 C99 是不公平的,除非您正在处理被认为是 GCC 中的错误的极端情况。 @Joshua,我认为 Roger 谈到了 K&R 和 pcc 历史编译器。在使用此端口编译时,在 PDP-10 上运行 C99 合规性测试套件之前声称它符合 C99 也是不公平的(可能存在来自移植和机器本身的错误)。但预计它会像 x86 上的 GCC3.2 一样接近 C99 标准。 @Joshua:在 C99 中,CHAR_BIT 允许大于 8,但 sizeof(char) 仍必须为 1(当我离开该评论时,这个答案大不相同)。我不是说 GCC3 不合规,C89 在这里提出了同样的要求,顺便说一句。我引用那段文字说 osgx 是担心 C99 合规性并使用 C99 编译器的人,所以他为什么担心非 C99 编译器? 这里是 PDP-10 GCC 的作者。 CHAR_BIT 为 9,但 sizeof(char) 仍为 1。

以上是关于是否存在 sizeof(char) != 1 或至少 CHAR_BIT > 8 的机器?的主要内容,如果未能解决你的问题,请参考以下文章

在 C 中,为啥 sizeof(char) 为 1,而 'a' 是 int?

关于sizeof的几个问题

字符与字符串3——char 的大小

【50分】动态申请指针数组 ptr = malloc(sizeof(char *) * n);这申请了多大的内存?

实现sizeof

C语言中sizeof的用法