获取此代码片段
void thing(signed short ss);
void test(int i){
thing((signed short)i);
}
gcc 和 clang 都会生成
movswl %di, %edi
jmp thing(int)
但是我知道参数在-32768和32767之间。并且我无法更改任何参数类型。所以 movswl 基本上是一个 nop。事实上,gcc 每次收到短参数时都会进行截断。所以它实际上在某些函数调用中每个函数都会截断两次。
理想情况下,我想要一种assert_within_bounds_cast函数,它是reinterpret_cast和bit_cast之间的交叉,基本上说“不用担心截断,只需使用最方便的寄存器大小”。我尝试使用
__builtin_unreachable()
和 reinterpret_cast
自己构建它,但它并不能始终如一地工作,有时会让事情变得更糟。
如果您无法将参数类型更改为
test
,那么您就会陷入困境 - 调用者不可能知道您的函数在接受 signed short
时需要 int
(其中 可能 更宽,但不是总是),并且该函数的调用者可能会向它传递一个超出您控制范围的int
可以重载该函数吗?
void thing(signed short ss);
void test(int i){
// consider asserting here too
thing((signed short)i);
}
void test(signed short i){
thing(i);
}
最后,在分析真正微不足道/不具有代表性的情况的结果时要小心 - 如果你真的有
void
函数而没有可变参数,那么当应用(进一步)优化时它们可能会被完全丢弃,所以你不能轻易地存在两种完全优化都运行的情况(可能会发现并修复您的情况)并且函数根本存在!