我很想知道如果我给无符号变量赋一个负值会发生什么.
代码看起来有点像这样.
unsigned int nVal = 0;
nVal = -5;
Run Code Online (Sandbox Code Playgroud)
它没有给我任何编译器错误.当我运行程序时,nVal分配了一个奇怪的值!是否可以将某个2的补码值分配给nVal?
情况如下:
现在在64位机器上,哪个语句是正确的(如果有的话):
假设由于溢出,带符号的二进制整数11111111001101100000101011001000只是负数.这是一个实际存在的问题,因为您可能希望分配比在32位整数中描述的更多的字节.但后来它被读入64位整数.
Malloc将其读取为64位整数,发现11111111001101100000101011001000#################################是一个通配符位,表示在原始整数之后存储的任何数据.换句话说,它读取接近其最大值2 ^ 64的结果并尝试分配一些quintillion字节.它失败.Malloc将其读取为64位整数,转换为0000000000000000000000000000000011111111001101100000101011001000,可能是因为它是如何加载到寄存器中而使大量位为零.它不会失败,但会分配负内存,就像读取正无符号值一样.Malloc读取它为64位整数,转换为################################11111111001101100000101011001000,可能是因为它是如何加载到寄存器中的#一个表示寄存器中先前数据的通配符.根据最后一个值,它无法完全失败.我实际测试了这个,导致malloc失败(这意味着1或3是正确的).我认为1是最合乎逻辑的答案.我也知道修复(使用size_t作为输入而不是int).
我真的想知道究竟发生了什么.出于某种原因,我没有找到任何关于如何在64位机器上实际处理32位整数以进行这种意外"演员"的澄清.我甚至不确定它在寄存器中是否真的很重要.
我知道,C标准很好地定义了(unsigned)-1必须产生2 ^ n-1,即一个无符号整数,其所有位都设置好.同样的道理(uint64_t)-1ll.但是,我在C11标准中找不到指定如何(uint64_t)-1解释的东西.
因此,问题是:C标准中是否有任何保证,以下哪项适用?
(uint64_t)-1 == (uint64_t)(unsigned)-1 //0x00000000ffffffff
(uint64_t)-1 == (uint64_t)(int64_t)-1 //0xffffffffffffffff
Run Code Online (Sandbox Code Playgroud) 我正在尝试获取某个无符号整数类型的最大值,而不包含任何像<limits>. 所以我想我只是翻转无符号整数值 0 的位。
#include <iostream>
#include <limits>
int main()
{
std::cout << (~0U) << '\n'; // #1
std::cout << (std::numeric_limits< unsigned >::max()) << '\n'; // #2
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我对这些之间的细微差别不是很有经验。这就是为什么我要问使用第一种方法是否会发生某些意外行为或某些平台/架构问题。