gpt4 book ai didi

符合规范的编译器能否中断 uint32_t -> int16_t -> int32_t 转换?

转载 作者:太空狗 更新时间:2023-10-29 16:54:03 27 4
gpt4 key购买 nike

最近,我们在一些旧代码中发现了奇怪的行为。这段代码已经工作了很长时间,但在某些平台(XBox 360、PowerPC)上崩溃了,编译器优化打开了最大。通常,我会怀疑未定义的行为。

代码大致如下:

#include <stdint.h>
uint32_t sign_extend16(uint32_t val)
{
return (int32_t)(int16_t)val;
}

它是模拟器的一部分,所以所讨论的操作应该不会太奇怪。通常,我希望它只考虑低 16 位并将其符号扩展到 32 位。显然,这是它多年来的行为。在 x86_64 上,GCC 给出了这个结果:

0000000000000000 <sign_extend16>:
0: 0f bf c7 movswl %di,%eax
3: c3 retq

但是,根据我对标准的理解,如果无法用有符号类型表示无符号类型的值,则未定义将无符号类型转换为有符号类型。

那么编译器是否可以假设无符号值必须在 [0, 32767] 范围内,因为任何其他值都未定义?在这种情况下,转换为 int16_t 和另一个转换为 int32_t 将无济于事。在这种情况下,编译器将代码转换为简单的移动是否合法?

最佳答案

两个整数类型之间的转换绝不是未定义的行为。

但是一些整数转换是实现定义的。

关于整数转换,C 说:

(C99, 6.3.1.3p3) "Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised."

此处记录了 gcc 在这种情况下的作用:

http://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html

"For conversion to a type of width N, the value is reduced modulo 2^N to be within range of the type; no signal is raised"

关于符合规范的编译器能否中断 uint32_t -> int16_t -> int32_t 转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9220448/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com