【发布时间】:2026-02-13 16:25:02
【问题描述】:
C 和 C++ 标准都允许同一整数类型的有符号和无符号变体互为别名。例如,unsigned int* 和 int* 可以别名。但这还不是全部,因为它们显然具有不同的可表示值范围。我有以下假设:
- 如果通过
int*读取unsigned int,则该值必须在int的范围内,否则会发生整数溢出并且行为未定义。这是正确的吗? - 如果通过
unsigned int*读取int,则负值会环绕,就好像它们被强制转换为unsigned int。这是正确的吗? - 如果该值在
int和unsigned int的范围内,则通过任一类型的指针访问它是完全定义的并给出相同的值。这是正确的吗?
另外,兼容但不等价的整数类型呢?
- 在
int和long具有相同范围、对齐等的系统上,int*和long*可以别名吗? (我假设不是。) - 可以
char16_t*和uint_least16_t*别名吗?我怀疑这在 C 和 C++ 之间有所不同。在 C 中,char16_t是uint_least16_t的类型定义(正确吗?)。在 C++ 中,char16_t是它自己的原始类型,它与uint_least16_t兼容。与 C 不同,C++ 似乎也不例外,允许兼容但不同的类型使用别名。
【问题讨论】:
-
“X 读取 Y”是什么意思?
-
X x = <value>; Y* yp = (Y*)&x; Y y = *yp;例如。 -
Annex J.3.5(实现定义的行为),C11 标准草案:
— The result of, or the signal raised by, converting an integer to a signed integer type when the value cannot be represented in an object of that type (6.3.1.3).我邀请您查看第 6.3.1.3 节。它回答了你的问题。 -
@EOF 谢谢!没有意识到转换的处理方式与算术溢出不同。
-
C 和 C++ 标准是为了适应一些非常奇怪的 CPU 架构而编写的,因此有一些看似合理的保证是不会实现的。然而,我们 99.9% 的人永远不会遇到奇怪的架构。您通常可以依靠编译器来简单地根据类型重新解释位模式。其他任何事情都是如此令人惊讶的结果,以至于它不可能在现实世界中持续存在。
标签: c++ c language-lawyer