我有一个简单的qmake C++项目:. profile文件:
CONFIG += c++17
QMAKE_CXXFLAGS += -O0 -ggdb3
target.path = /tmp/$${TARGET}/dev
INSTALLS += target
SOURCES += main.cpp
main.cpp文件:
#include <chrono>
#include <iostream>
using Seconds = std::chrono::duration<int, std::ratio<1, 1>>;
struct TimeSpan
{
Seconds seconds;
};
TimeSpan operator + (TimeSpan left, TimeSpan right) { return { left.seconds + right.seconds }; }
int main()
{
TimeSpan a = { Seconds(1) };
TimeSpan b = { Seconds(2) };
TimeSpan ab = a + b;
auto as = a.seconds;
auto bs = b.seconds;
auto abs = as + bs;
std::cout << a.seconds.count()
<< " + " << b.seconds.count()
<< " = " << ab.seconds.count()
<< " = " << (a + b).seconds.count() << std::endl;
std::cout << as.count()
<< " + " << bs.count()
<< " = " << abs.count()
<< " = " << (as + bs).count() << std::endl;
return 0;
}
程序正确打印
但是当我在return 0;
上放置一个断点并查看表达式求值器时,事情变得疯狂起来:
b、B、as、bs和abs的值正确(1 + 2 = 3)。但由于某种原因,它显示了一个疯狂的值1431658504((hex)55556008)用于在表达式求值器中添加a + b
,但它根本不能执行as + bs
。(例如,单步、修改赋值器、更改显示格式等)导致值更改:
现在它显示-7352((hex)ffffffffffffeffe 348),并且现在它停留在那个值。
这是怎么回事?程序非常简单。调试器真的会在这么简单的计算上出错吗?我该怎么做才能让它正确运行?
我使用的是Qt Creator 5.0.2
此问题在多个目标体系结构(x86和ARM)上仍然存在,但错误值不同。
1条答案
按热度按时间kh212irz1#
但是,当我在
return 0;
上放置断点并查看表达式求值器时,事情变得非常复杂问:局部变量是在
return 0;
行的 * 之前、* 之后还是“中间”被析构?您可以通过以下方式了解
1.拆卸
main
和1.在命中断点时查看指令指针。
事实上,“things go crazy”表明断点是在
as
和bs
的作用域结束之后,也是在所有局部变量都被析构之后......在这种情况下,对它们进行求值会产生未定义的行为(此时您正在查看随机内存,因此错误的值在架构之间发生变化并不奇怪)。这在某种程度上是意料之中的:调试器无法知道您的意图是在析构函数之前停止。
您可以选择