unsigned int 和 unsigned long int 之间的 C++ 区别

标签 c++ visual-studio gcc g++

我正在使用 Visual Studio 编译器在 Windows 上进行 C++ 开发,特别是 Visual Studio 2015 Update 3。

对于一些与 DSP 相关的工作,我正在使用 unsigned int/unsigned long 数据类型。我想知道这两个内置的 C/C++ 类型之间有什么区别。

我通过 Google 和 SO 搜索了一下,找到了这些引用资料。

  1. Types documentation在 cppreference.com 上
  2. Types documentation在 MSDN for Visual Studio 2015 上
  3. Types documentation对于 GNU C/C++(因为 G++ compiler 指出 C/C++ 使用相同的默认类型实现,我在这里引用 C 文档)

我假设 cppreference 文档是 ISO C++11 标准的总结。因此,根据 LP/ILP 32/64 数据模型,“标准”unsignedunsigned int 是 16/32 位,而 unsigned longunsigned long int 是 32/64 位,具体取决于 LP/ILP 32/64 数据模型。

对于 MSDN 和 GNU 文档,它们都声明 unsigned int/unsigned long 正在使用 32 位实现并且最多可以保存 4,294,967,295 的值。但是 GNU 文档还指出,根据您的系统,unsigned long 可以是 64 位,它与 unsigned long long int 相同。

所以我的问题如下:

  1. 对于 unsigned long 64 位,超出上限 4,294,967,295 是未定义行为还是正确行为?
  2. 如果我有一个在 Visual Studio 中编译的 Windows 系统上运行的应用程序,则基本 unsigned == unsigned long。对还是错?
  3. 如果我有一个由 GNU 编译器在 Linux/Windows 上编译的应用程序,我必须确定 unsigned long == unsigned intunsigned long == unsigned long long 以避免数据溢出。对或错
  4. 如果我有一个可能由所有这些 Visual Studio/GNU/Clang/Intel 编译器编译的跨平台应用程序,我必须使用一堆预处理器对环境进行明确分类,以避免数据溢出。对或错

提前致谢。

编辑: 感谢@PeterRuderman 指出无符号类型的超出 ceil 值不是未定义的行为。

那么我的问题1会变成:

  1. 对于 unsigned long 64 位,超出上限 4,294,967,295 是否会导致自身回绕?

最佳答案

简短的回答是,是的,sizeof(unsigned)不保证等于 sizeof(unsigned long)但它恰好在 MSVC 中。如果您需要以独立于平台的方式确定地知道整数的大小,请使用 <cstdint> 中的类型: uint32_tuint64_t .避免 long在可移植代码中,它会导致很多令人头疼的问题。

另请注意,无符号 整数溢出不是未定义的行为。定义的行为是值回绕。 (例如 std::numeric_limits< uint64_t >::max() + 43 == 42 )。对于溢出是未定义行为的signed 类型而言,情况并非如此。

要回答您的最后一个问题,64 位整数可以存储 [0, 264 - 1] 范围内的值。 232 + 1 不会导致环绕。

关于unsigned int 和 unsigned long int 之间的 C++ 区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43403613/

相关文章:

c++ - 为什么大括号初始化赋值会用垃圾填充变量?

c - 无论如何在没有 pthread.h 的情况下在 C 中使用线程?

c - 读写整数数组到共享内存

c++ - exclude/usr/include/c++/4.3/in用intel编译器编译代码

macos - "___emutls_get_address"符号是什么?

c++ - 更新 Vector 中对象的属性

c++ - 混合版本的 MSVCRT

c++ - 如何在 C++ 中修复 Visual Studio locals/watches(调试版本)

visual-studio - Visual Studio 相对引用路径

c++ - ProtocolBuffer 无法定义数据,尽管它已被接收