C/C++中整数类型别名的标准保证是什么?例如:"unsigned"总是等于"unsigned int"吗?

24 浏览
0 Comments

C/C++中整数类型别名的标准保证是什么?例如:"unsigned"总是等于"unsigned int"吗?

第一个问题:

  • “unsigned”总是等同于“unsigned int”吗?
  • “signed”总是等同于“int”吗?
  • “short”总是等同于“signed short”吗?
  • ...

第二个问题:

如果C/C++标准对上述问题给出了答案,那么相关的段落是哪些?

0
0 Comments

C/C++中整数类型的别名标准保证是什么?例如,"unsigned"是否总是等于"unsigned int"?

这个问题的出现是因为在C/C++中,存在一些整数类型的别名,比如"unsigned"和"unsigned int"。这些别名是否总是等价的,即它们表示的类型是否总是相同的,是一个需要讨论和解决的问题。

首先,在C++11标准中,通过查阅§7.1.6.2[dcl.type.simple]/table 10,我们可以找到所有简单类型说明符(以及它们的组合)以及它们的含义。这个表格列举了许多类型说明符及其对应的类型,比如:

unsigned      => unsigned int
unsigned int  => unsigned int
signed        => int
signed int    => int
int           => int

这表明了"unsigned"和"unsigned int"是等价的。

类似地,C11标准在§6.7.2/2中也有类似的映射(尽管格式不同,但是对于C和C++共有的类型,它们指定了相同的等价组合)。

需要注意的是,在C++中,"char"、"signed char"和"unsigned char"是三种不同的类型。而在C中,"char"是有符号的还是无符号的是由实现定义的。

但是,在C和C++中,"char"、"signed char"和"unsigned char"仍然是三种不同的类型。只是在C中,"char"是有符号的还是无符号的是由实现定义的。

在C++中,类型的身份是相关的,它与许多语言结构(如函数重载或模板实例化)相关,比如"char"、"signed char"和"unsigned char"是三个不同的有效重载,而在C中,类型的身份并不是那么重要。

另外,在C中,是否可以将"char *"赋值给"signed char *"是由编译器定义的。在C99中,至少在C中是不允许的。在我的GCC(4.7.2)中,即使是将"char *"赋值给"signed char *",也会发出这样的警告(-Wpointer-sign),因为"char"是有符号的。

根据C 2018 6.5.16.1 1(C 2011和C 1999也一样),将不同类型的指针赋值给彼此是违反约束的,除非赋值语句中添加了限定符,并且右操作数可以是带有限定符的"void *"。

然而,在C和C++中,可以自由地转换指针的类型。虽然6.5.16.1描述了赋值的语法,但是赋值的语义是在6.3.2.3(7)中描述的。允许自由地赋值不同类型的指针。但是,如果对该指针进行解引用是否是未定义行为,在6.5(7)中进行了描述,它要求"char"类型的对象只能由一个具有以下类型之一的lvalue表达式访问:"*字符类型"。因此,如果IUIC,可以使用"signed char"类型的指针来读取"char"类型的值,反之亦然。

需要注意的是,虽然"char"可以用来读取"signed char",反之亦然,但是对于其他类型(如"int"和"unsigned int")来说通常并不成立。自由地将不同类型的指针互相赋值将导致违反别名规则。

C/C++中整数类型的别名标准保证了一些类型的等价性,但是对于"char"类型的符号性质以及指针之间的赋值操作仍然有一些限制和不确定性。

0