符合标准的编译器是否可以破坏uint32_t – > int16_t – > int32_t转换?

最近,我们在一些旧代码中发现了奇怪的行为.这段代码已经工作了很长时间,但在某些平台(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”

相关文章

Windows2012R2备用域控搭建 前置操作 域控主域控的主dns:自...
主域控角色迁移和夺取(转载) 转载自:http://yupeizhi.blo...
Windows2012R2 NTP时间同步 Windows2012R2里没有了internet时...
Windows注册表操作基础代码 Windows下对注册表进行操作使用的...
黑客常用WinAPI函数整理之前的博客写了很多关于Windows编程的...
一个简单的Windows Socket可复用框架说起网络编程,无非是建...