C++ 什么时候 uint8_t ≠ unsigned char?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16138237/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 20:06:14  来源:igfitidea点击:

When is uint8_t ≠ unsigned char?

c++ctypesunsigned-charuint8t

提问by user541686

According to C and C++, CHAR_BIT >= 8.
But whenever CHAR_BIT > 8, uint8_tcan't even be represented as 8 bits.
It must be larger, because CHAR_BITis the minimum number of bits for any data type on the system.

据C和C ++, CHAR_BIT >= 8
但是每当CHAR_BIT > 8,uint8_t甚至不能表示为 8 位。
它必须更大,因为它CHAR_BIT是系统上任何数据类型的最小位数。

On what kind of a system can uint8_tbe legally defined to be a type other than unsigned char?

什么样的系统可以uint8_t合法地定义为除 之外的类型unsigned char

(If the answer is different for C and C++ then I'd like to know both.)

(如果 C 和 C++ 的答案不同,那么我想知道两者。)

采纳答案by R.. GitHub STOP HELPING ICE

If it exists, uint8_tmust always have the same width as unsigned char. However, it need not be the same type; it may be a distinct extended integer type. It also need not have the same representation as unsigned char; for instance, the bits could be interpreted in the opposite order. This is a silly example, but it makes more sense for int8_t, where signed charmight be ones complement or sign-magnitude while int8_tis required to be twos complement.

如果存在,则uint8_t必须始终与 具有相同的宽度unsigned char。但是,它不必是相同的类型;它可能是一个不同的扩展整数类型。它也不需要与unsigned char;具有相同的表示形式。例如,可以以相反的顺序解释这些位。这是一个愚蠢的例子,但它更有意义int8_t,其中signed char可能是一个补码或符号大小,而int8_t需要是二进制补码。

One further "advantage" of using a non-char extended integer type for uint8_teven on "normal" systems is C's aliasing rules. Character types are allowed to alias anything, which prevents the compiler from heavily optimizing functions that use both character pointers and pointers to other types, unless the restrictkeyword has been applied well. However, even if uint8_thas the exact same size and representation as unsigned char, if the implementation made it a distinct, non-character type, the aliasing rules would not apply to it, and the compiler could assume that objects of types uint8_tand int, for example, can never alias.

uint8_t即使在“正常”系统上使用非字符扩展整数类型的另一个“优势”是 C 的别名规则。字符类型可以给任何东西做别名,这会阻止编译器大量优化同时使用字符指针和指向其他类型的指针的函数,除非restrict关键字应用得很好。但是,即使与uint8_t具有完全相同的大小和表示形式unsigned char,如果实现使其成为不同的非字符类型,则别名规则也不适用于它,并且编译器可以假设类型的对象uint8_tint,例如,可以从不别名。

回答by autistic

On what kind of a system can uint8_tbe legally defined to be a type other than unsigned char?

什么样的系统可以uint8_t合法地定义为除 之外的类型unsigned char

In summary, uint8_tcan only be legally defined on systems where CHAR_BITis 8. It's an addressable unit with exactly 8 value bits and no padding bits.

总之,uint8_t只能在CHAR_BIT是 8 的系统上合法定义。它是一个可寻址单元,具有恰好 8 个值位且没有填充位。

In detail, CHAR_BITdefines the width of the smallest addressable units, and uint8_tcan't have padding bits; it can only exist when the smallest addressable unit is exactly 8 bits wide. Providing CHAR_BITis 8, uint8_tcan be defined by a type definition for any 8-bit unsigned integer type that has no padding bits.

详细地,CHAR_BIT定义了最小可寻址单元的宽度,并且uint8_t不能有填充位;它只能在最小可寻址单元正好是 8 位宽时存在。提供CHAR_BIT是 8,uint8_t可以由任何没有填充位的 8 位无符号整数类型的类型定义来定义。



Here's what the C11 standard draft (n1570.pdf) says:

这是 C11 标准草案 (n1570.pdf) 所说的:

5.2.4.2.1 Sizes of integer types1 The values given below shall be replaced by constant expressions suitable for use in #if preprocessing directives. ... Their implementation-defined values shall be equal or greater in magnitude (absolute value) to those shown, with the same sign.

-- number of bits for smallest object that is not a bit-field (byte)
   CHAR_BIT                                            8

5.2.4.2.1 整数类型的大小1 下面给出的值应替换为适用于#if 预处理指令的常量表达式。...它们的实现定义的值在幅度(绝对值)上应等于或大于所示值,并具有相同的符号。

-- number of bits for smallest object that is not a bit-field (byte)
   CHAR_BIT                                            8

Thus the smallest objects must contain exactly CHAR_BIT bits.

因此,最小的对象必须恰好包含 CHAR_BIT 位。



6.5.3.4 The sizeof and _Alignof operators

...

4 When sizeof is applied to an operand that has type char, unsigned char, or signed char, (or a qualified version thereof) the result is 1. ...

6.5.3.4 sizeof 和 _Alignof 运算符

...

4 当 sizeof 应用于具有 char、unsigned char 或 signed char 类型(或其限定版本)的操作数时,结果为 1。...

Thus, those are (some of) the smallest addressable units. Obviously int8_tand uint8_tmay also be considered smallest addressable units, providing they exist.

因此,那些是(一些)最小的可寻址单元。显然int8_t并且uint8_t也可以被认为是最小的可寻址单元,前提是它们存在。

7.20.1.1 Exact-width integer types

1 The typedef name intN_t designates a signed integer type with width N, no padding bits, and a two's complement representation. Thus, int8_t denotes such a signed integer type with a width of exactly 8 bits.

2 The typedef name uintN_t designates an unsigned integer type with width N and no padding bits. Thus, uint24_t denotes such an unsigned integer type with a width of exactly 24 bits.

3 These types are optional.However, if an implementation provides integer types with widths of 8, 16, 32, or 64 bits, no padding bits, and (for the signed types) that have a two's complement representation, it shall define the corresponding typedef names.

7.20.1.1 精确宽度整数类型

1 typedef 名称 intN_t 指定宽度为 N、无填充位和二进制补码表示的有符号整数类型。因此, int8_t 表示宽度正好为 8 位的带符号整数类型。

2 typedef 名称 uintN_t 指定宽度为 N 且无填充位的无符号整数类型。因此, uint24_t 表示宽度正好为 24 位的无符号整数类型。

3这些类型是可选的。但是,如果实现提供宽度为 8、16、32 或 64 位、无填充位且(对于有符号类型)具有二进制补码表示的整数类型,则应定义相应的 typedef 名称。

The emphasis on "These types are optional" is mine. I hope this was helpful :)

强调“这些类型是可选的”是我的。我希望这可以帮到你 :)

回答by zwol

A possibility that no one has so far mentioned: if CHAR_BIT==8and unqualified charis unsigned, which it is in some ABIs, then uint8_tcould be a typedef for charinstead of unsigned char. This matters at least insofar as it affects overload choice (and its evil twin, name mangling), i.e. if you were to have both foo(char)and foo(unsigned char)in scope, calling foowith an argument of type uint8_twould prefer foo(char)on such a system.

到目前为止没有人提到的一种可能性:如果CHAR_BIT==8和 unqualifiedchar是无符号的,它在某些 ABI 中,那么uint8_t可能是一个 typedef forchar而不是unsigned char。这至少在它影响重载选择(及其邪恶的孪生兄弟,名称修改)方面很重要,即如果您同时拥有foo(char)foo(unsigned char)范围,那么在这样的系统上调用foo类型参数uint8_t会更受欢迎foo(char)