相关疑难解决方法(0)

在C++中有符号整数溢出仍然是未定义的行为吗?

众所周知,有符号整数溢出是未定义的行为.但是C++ 11 cstdint文档中有一些有趣的东西:

有符号整数类型,宽度分别为8,16,32和64位,没有填充位,负值使用2的补码(仅当实现直接支持该类型时提供)

见链接

这里是我的问题:由于标准明确地说,对int8_t,int16_t,int32_tint64_t负数是2的补,仍然是这些类型的未定义行为的泛滥?

编辑我检查了C++ 11和C11标准,这是我发现的:

C++ 11,§18.4.1:

标题定义了所有函数,类型和宏,与C标准中的7.20相同.

C11,§7.20.1.1:

typedef名称intN_t指定有符号整数类型,其宽度为N,无填充位和二进制补码表示.因此,int8_t表示这样的带符号整数类型,其宽度恰好为8位.

c++ integer-overflow undefined-behavior c++11

74
推荐指数
2
解决办法
2万
查看次数

为什么 C++20 中计算导致的有符号溢出仍然是未定义行为

通过这个回答我才知道:

由于计算而导致的有符号溢出在 C++20 中仍然是未定义的行为,而由于转换而导致的有符号溢出在 C++20 中得到了明确定义(这是为 Pre-C++20定义的实现)。

由于转换导致的有符号溢出的变化是因为 C++20 编译器要求使用 2 的补码。

我的问题是

如果编译器需要使用 C++20 中的 2 的补码,那么为什么由于计算而导致的有符号溢出不像由于转换而导致的有符号溢出那样被明确定义?

也就是说,计算溢出和转换溢出之间为什么(如何)存在差异。从本质上讲,为什么这两种溢出的处理方式不同。

c++ signed overflow type-conversion c++20

7
推荐指数
1
解决办法
1433
查看次数

为什么这句话:"未定义的行为意味着编译器可以做任何想做的事情"是真的吗?

具体参考:https://blogs.msdn.microsoft.com/oldnewthing/20140627-00/?p = 633 /

我是一名新的C++程序员,我目前正在学习未定义的行为及其对程序的影响.我特意链接到上面的博客,该博客说当发生未定义的行为时,任何事情都可能发生.

它特别提到了几次,当发生未定义的行为时,编译器可以允许任何事情发生.

具体是什么导致这种情况发生,为什么会发生?

c++ compiler-construction undefined-behavior

6
推荐指数
2
解决办法
321
查看次数

C++中签名的Integer值溢出?

我有一个遗留的代码库,我们正试图从中迁移devtoolset-4devtoolset-7.我注意到有关有符号整数溢出的有趣行为(int64_t具体而言).

有一个代码片段,用于检测整数溢出,同时乘以一大组整数:

// a and b are int64_t
int64_t product = a * b; 
if (b != 0 && product / b != a) {
    // Overflow
}
Run Code Online (Sandbox Code Playgroud)

这段代码与devtoolset-4一起工作正常.但是,使用devtoolset-7时,永远不会检测到溢出.

例如:当a = 83802282034166b = 98765432, product变为-5819501405344925872(显然值已溢出).

product / b结果价值等于a (83802282034166).因此,if情况永远不会成真.它的值应该根据overflown(负)product值计算:-5819501405344925872 / 98765432 = -58922451788

具有讽刺意味的是,数学是正确的,但它导致devtoolset-4的异常行为.

  • 编译器是否可以缓存该值(而不是重新评估它)导致此行为?
  • 或者编译器优化是否将语句转换product / b != aproduct != a * b并达到相同的溢出值(或者可能只是根据上面的语句跳过计算 …

c++ integer-overflow devtoolset

4
推荐指数
2
解决办法
601
查看次数