【发布时间】:2018-06-29 12:28:31
【问题描述】:
我有以下代码,它在 GDB 中的行为似乎很奇怪,具体取决于复制/移动构造函数是否默认。
#include <iostream>
#define CUSTOM 0
class Percentage
{
public:
using value_t = double;
Percentage() = default;
~Percentage() = default;
template <typename T>
Percentage(T) = delete;
Percentage(value_t value):
m_value(value)
{}
#if CUSTOM == 1
Percentage(const Percentage& p):
m_value(p.m_value)
{}
Percentage& operator=(const Percentage& p)
{
m_value = p.m_value;
return *this;
}
Percentage(Percentage&& p):
m_value(std::move(p.m_value))
{}
Percentage& operator=(Percentage&& p)
{
m_value = std::move(p.m_value);
return *this;
}
#else
Percentage(const Percentage&) = default;
Percentage& operator=(const Percentage&) = default;
Percentage(Percentage&&) = default;
Percentage& operator=(Percentage&&) = default;
#endif
friend std::ostream& operator<<(std::ostream& os, const Percentage& p)
{
return os << (p.m_value * 100.0) << '%';
}
private:
value_t m_value = 0.0;
};
struct test
{
Percentage m_p;
void set(const Percentage& v) { m_p = v; }
Percentage get() const { return m_p; }
};
int main()
{
test t;
std::cout << "Value 1: " << t.get() << std::endl;
t.set(42.0);
std::cout << "Value 2: " << t.get() << std::endl;
std::cout << "Breakpoint here" << std::endl;
}
我启动 GDB,在 main 的最后一个 cout 上添加一个断点并运行“p t.get()”,我希望它是 42,但取决于宏 CUSTOM 的值,我得到 42(当 CUSTOM为 1) 或 0(当 CUSTOM 为 0 时)。
发生了什么?这是编译器gdb中的错误吗?
OS: Fedora 26
Compiler: gcc 7.3.1
Flags: -fsanitize=address,leak -O0 -g3 -std=c++17
GDB 8.0.1-36
【问题讨论】:
-
请注意,
p t显示了对象的正确内容。p t.get()需要调试器执行应用代码,gdb显然搞错了。 -
我怀疑问题是 p.get() 返回一个临时的。您可以尝试相同的方法,但将 get 的签名从“Percentage get() const”更改为“Percentage const & get() const”并查看报告的值是否正常?
-
@SamVarshavchik 是吗?此处不是强制使用 RVO,即没有返回任何内容。
-
@Walter 我观察到与 Sam 相同的行为
-
被删除的模板构造函数是怎么回事???