Short* 到 int* 之间的转换

发布于 2024-12-21 14:48:08 字数 149 浏览 3 评论 0原文

假设在 32 位操作系统上,short 为 2 个字节,int 为 4 个字节。以下是未定义的行为吗?

short s = 42;
int *p = (int*)(&s);

Assuming short is 2 bytes and int is 4 bytes on a 32 bit OS. Is the following an undefined behavior?

short s = 42;
int *p = (int*)(&s);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

分開簡單 2024-12-28 14:48:09

不,您发布的代码不会表现出未定义的行为,但尝试读取*p会表现出未定义的行为。另外,根据 intshort 的对齐要求,转换的结果可能是未指定且不可逆的(参见 5.2.10 [expr.reinterpret.cast] / 7 )。

参见 ISO/IEC 14882:2011 3.10 [basic.lval] / 10:

如果程序尝试通过以下类型之一以外的泛左值访问对象的存储值,则行为未定义:

  • 对象的动态类型,
  • 对象动态类型的 cv 限定版本,
  • 与对象的动态类型类似(如 4.4 中定义)的类型,
  • 与对象的动态类型相对应的有符号或无符号类型,
  • 是与对象动态类型的 cv 限定版本相对应的有符号或无符号类型,
  • 在其元素或非静态数据成员中包含上述类型之一的聚合或联合类型(递归地包括子聚合或包含的联合的元素或非静态数据成员),
  • 该类型是对象动态类型的(可能是 cv 限定的)基类类型,
  • char 或 unsigned char 类型。

您尝试访问的对象是 short,而 *pint 类型的 glvalue,它不会不符合上述任何描述。

No, the code that you have posted does not exhibit undefined behavior but attempting to read *p would. Also, depending on the alignment requirements of int and short, the result of the cast may be unspecified and irreversable (see 5.2.10 [expr.reinterpret.cast] / 7).

See ISO/IEC 14882:2011 3.10 [basic.lval] / 10:

If a program attempts to access the stored value of an object through a glvalue of other than one of the following types the behavior is undefined:

  • the dynamic type of the object,
  • a cv-qualified version of the dynamic type of the object,
  • a type similar (as defined in 4.4) to the dynamic type of the object,
  • a type that is the signed or unsigned type corresponding to the dynamic type of the object,
  • a type that is the signed or unsigned type corresponding to a cv-qualified version of the dynamic type of the object,
  • an aggregate or union type that includes one of the aforementioned types among its elements or non-static data members (including, recursively, an element or non-static data member of a subaggregate or contained union),
  • a type that is a (possibly cv-qualified) base class type of the dynamic type of the object,
  • a char or unsigned char type.

The object that you are trying to access is a short and *p is a glvalue of type int which doesn't meet any of the above descriptions.

浪漫之都 2024-12-28 14:48:09

您的代码直接位于 UB 领域,因为您正在读取两个未初始化的字节。
相反的情况

int b
short* f = (short *) &b

然而,由于小端架构的语义,

可能会起作用。 (这一切都假设编译器没有做任何愚蠢的事情)

来自维基百科:

little-endian系统具有相同的值可以被
以不同的长度从内存中读取,而不使用不同的
地址(即使施加了对齐限制)。例如,
可以读取内容为 4A 00 00 00 的 32 位内存位置
与 8 位(值 = 4A)、16 位(004A)、24 位地址相同
(00004A),或32位(0000004A),所有这些都保留相同的数字
价值。尽管这个小端属性很少被直接使用
对于高级程序员来说,它经常被代码优化器用作
以及汇编语言程序员。

所以,只要你是小端,相反的方向应该没问题。

但仍然是未定义的行为。

Your code is directly in the realm of UB, as you are reading two uninitialized bytes.
However, the opposite,

int b
short* f = (short *) &b

will probably work due to the semantics of the little endian architecture.

(This is all assuming the compiler doesn't do anything stupid)

From wikipedia:

The little-endian system has the property that the same value can be
read from memory at different lengths without using different
addresses (even when alignment restrictions are imposed). For example,
a 32-bit memory location with content 4A 00 00 00 can be read at the
same address as either 8-bit (value = 4A), 16-bit (004A), 24-bit
(00004A), or 32-bit (0000004A), all of which retain the same numeric
value. Although this little-endian property is rarely used directly by
high-level programmers, it is often employed by code optimizers as
well as by assembly language programmers.

So, as long as you are little endian, the opposite direction should be fine.

Still undefined behavior though.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文