短类型的 C++ 溢出
C++ overflow of short type
我尝试了以下代码 snipped:
int main()
{
short i = 0;
do
{
if (i + (short) 1 < (short) 0)
std::cout << "MAX: " << i << std::endl;
i++;
} while (i > 0);
std::cout << "MIN: " << i << std::endl;
return 0;
}
我预计此代码将输出 short
类型的最大值和最小值。但它只输出最小值:
MIN: -32768
我猜 for
循环内的比较是使用 int
类型计算的。但是我不明白为什么如果所有参数都具有 short
类型,编译器会执行扩展。
我使用 MS Visual Studio 2013,x32 版本对其进行了测试。
您的代码的行为未定义,因为您最终会溢出 signed
整数类型。
如果您想了解数据类型的各种限制,请根据您的情况使用
std::numeric_limits<short>::min()
和 std::numeric_limits<short>::max()
等
永远不要依赖有符号计数器 "clocking" 从最大值到最小值的循环。
我可以看出逻辑是这样的,它只会显示一个 MIN。可能您需要更改代码中的比较逻辑以获得 MAX 和 MIN。
即..if (i + (short) 1 > (short) 0)
此外,不要忘记限制值的数量,否则您将陷入无限循环
回答你的问题:"why does the compiler widen arguments to int when they are all short?"答案是"because the standard says it must"。所有带符号操作数实际窄于 int
的算术运算必须首先扩展为 int
。 (实际上比 int
窄的操作数可能是 char
、short
和 wchar_t
。)
某些参数无符号时的规则更复杂(我永远记不住)。
旁白:正如其他人所指出的,如果您溢出了一个带符号的类型,编译器可以生成格式化您的硬盘的代码。不要这样做。特别是,GCC 很可能发现 i
从零开始递增,因此它总是大于零并删除测试 - 所以你将有一个无限循环。
我尝试了以下代码 snipped:
int main()
{
short i = 0;
do
{
if (i + (short) 1 < (short) 0)
std::cout << "MAX: " << i << std::endl;
i++;
} while (i > 0);
std::cout << "MIN: " << i << std::endl;
return 0;
}
我预计此代码将输出 short
类型的最大值和最小值。但它只输出最小值:
MIN: -32768
我猜 for
循环内的比较是使用 int
类型计算的。但是我不明白为什么如果所有参数都具有 short
类型,编译器会执行扩展。
我使用 MS Visual Studio 2013,x32 版本对其进行了测试。
您的代码的行为未定义,因为您最终会溢出 signed
整数类型。
如果您想了解数据类型的各种限制,请根据您的情况使用
std::numeric_limits<short>::min()
和 std::numeric_limits<short>::max()
等
永远不要依赖有符号计数器 "clocking" 从最大值到最小值的循环。
我可以看出逻辑是这样的,它只会显示一个 MIN。可能您需要更改代码中的比较逻辑以获得 MAX 和 MIN。
即..if (i + (short) 1 > (short) 0)
此外,不要忘记限制值的数量,否则您将陷入无限循环
回答你的问题:"why does the compiler widen arguments to int when they are all short?"答案是"because the standard says it must"。所有带符号操作数实际窄于 int
的算术运算必须首先扩展为 int
。 (实际上比 int
窄的操作数可能是 char
、short
和 wchar_t
。)
某些参数无符号时的规则更复杂(我永远记不住)。
旁白:正如其他人所指出的,如果您溢出了一个带符号的类型,编译器可以生成格式化您的硬盘的代码。不要这样做。特别是,GCC 很可能发现 i
从零开始递增,因此它总是大于零并删除测试 - 所以你将有一个无限循环。