我想定义一个带有unsigned intas参数的函数,并向参数返回一个int全等模UINT_MAX + 1.
第一次尝试可能如下所示:
int unsigned_to_signed(unsigned n)
{
return static_cast<int>(n);
}
Run Code Online (Sandbox Code Playgroud)
但正如任何语言律师所知,从无符号转换为大于INT_MAX的已签名值是实现定义的.
我想实现这一点,以便(a)它只依赖于规范规定的行为; (b)它在任何现代机器上编译成无操作并优化编译器.
对于奇怪的机器......如果没有签名的int congruent将UINT_MAX + 1模数为unsigned int,那么假设我想抛出一个异常.如果有多个(我不确定这是否可能),那么就说我想要最大的一个.
好的,第二次尝试:
int unsigned_to_signed(unsigned n)
{
int int_n = static_cast<int>(n);
if (n == static_cast<unsigned>(int_n))
return int_n;
// else do something long and complicated
}
Run Code Online (Sandbox Code Playgroud)
当我不是一个典型的二元补充系统时,我并不太关心效率,因为我认为不太可能.如果我的代码成为2050年无所不在的符号量级系统的瓶颈,那么,我敢打赌,有人可以解决这个问题并对其进行优化.
现在,第二次尝试非常接近我想要的.尽管转换int为某些输入的实现定义,但是unsigned标准保证转换为保留模UINT_MAX + 1的值.所以条件确实检查我想要什么,它将在我可能遇到的任何系统上编译成什么.
但是......我仍然在int没有首先检查它是否会调用实现定义的行为.在2050年的一些假设系统中,它可以做谁知道什么.所以我想说我想避免这种情况.
问题:我的"第三次尝试"应该是什么样的?
回顾一下,我想:
[更新]
让我举一个例子来说明为什么这不是一个微不足道的问题.
考虑具有以下属性的假设C++实现:
sizeof(int) 等于4sizeof(unsigned) 等于4INT_MAX 等于32767INT_MIN等于-2 …考虑以下主机功能:
uint64_t * SomeDevPtr =...
/* Where SomeDevPtr is a pointer pointed to some device memory address allocated by cudaMalloc(); */
uint32_t * SomeDevIntPtr = reintepret_cast<uint32_t *>(SomeDevPtr);
Run Code Online (Sandbox Code Playgroud)
由于该功能,cudaMalloc将automatcially fullfill一些aligment要求(我认为它对准一些128字节存储器边界),因此,我认为无论是SomeDevIntPtr和SomeDevPtr应在GPU的全局内存确切相同的物理内存地址开始,我是正确的这一?
我只是想确定一下,因为我编写的一些函数依赖于它.