C++ 将无符号整数转换为有符号整数可移植性

loo*_*oop 0 c++ standards signed

我知道在 C 中,无符号整数到有符号整数的转换是实现定义的,但是对于 C++ 来说它是什么?我想已经有人问过这个问题了,我搜索了一下,但没有找到。

我有一个对无符号整数进行操作并返回相关无符号整数的函数。我通过转换为类似于 的无符号整数来向该函数传递一个有符号整数int num = -6; unsigned ret = func((unsigned)num); int ret_as_signed = (int)ret;。在 Visual Studio 中工作正常,但我想知道它的可移植性如何。

是否有一种可移植的方法将无符号整数转换为有符号整数?是否可以通过环绕反转有符号整数如何转换为无符号整数?谢谢

ric*_*ici 6

由于 C++20 最终摆脱了补码和符号数值整数,因此有符号和无符号整数之间的转换是定义良好且可逆的。所有标准整数类型现在都是 2 的补码,有符号和无符号之间的转换不会改变表示形式中的任何位。

\n

对于 C++20 之前的 C++ 版本,原始答案仍然适用。我将把它作为历史遗迹留下。

\n
\n

无符号整数到有符号整数的转换(其中无符号值超出有符号类型的范围)是实现定义的。您不能指望能够将负整数往返为无符号整数,然后再返回有符号整数。[1]

\n

C++ 标准,[conv.integral],\xc2\xa7 4.7/3:

\n
\n

如果目标类型是有符号的,并且可以用目标类型(和位字段宽度)表示,则该值不会改变;否则,该值是实现定义的。

\n
\n

[1] 看起来它可能会起作用,但不能保证。

\n


M.M*_*M.M 6

对于有符号->无符号转换逆的可移植版本,怎么样:

if ( ret <= INT_MAX )
    ret_as_signed = ret;
else
    ret_as_signed = -(int)(UINT_MAX - ret) - 1;
Run Code Online (Sandbox Code Playgroud)

您可能可以使用 中的模板来概括这一点<limits>。