【发布时间】:2018-08-21 19:44:52
【问题描述】:
尝试调试和理解一个似乎是移动构造函数的小问题,问题仅出现在 Visual Studio 2017 15.6.1,发布版本中。
这里是代码(重现问题最少):
#include <vector>
#include <iostream>
#include <algorithm>
#include <cstring>
const size_t kSize = 16;
class Symbol
{
public:
explicit Symbol(const char *const name = nullptr)
: name_{0}
{
if (name)
std::memcpy(name_, name, strlen(name));
}
Symbol(const Symbol& other)
{
std::memcpy(name_, other.name_, sizeof(name_));
}
Symbol& operator=(const Symbol& other)
{
if (this != &other)
std::memcpy(name_, other.name_, sizeof(name_));
return *this;
}
Symbol(Symbol&& other) noexcept
{
std::memcpy(name_, other.name_, sizeof(name_));
std::memset(other.name_, 0, sizeof(other.name_));
}
const char* GetSymbolName(void) const { return name_; }
private:
char name_[kSize];
};
struct MyTestMessage
{
Symbol symbol;
int32_t type;
int32_t other;
int32_t status;
int32_t reserved[5];
MyTestMessage() = default;
MyTestMessage(const MyTestMessage& msg) = default;
MyTestMessage(MyTestMessage&& msg) = default;
/*
MyTestMessage(MyTestMessage&& msg) noexcept
: symbol(std::move(msg.symbol))
{
status = msg.status;
other = msg.other;
type = msg.type;
}*/
};
void Print(const std::vector<MyTestMessage>& data)
{
std::cout << "------------" << std::endl;
std::for_each(data.cbegin(), data.cend(), [](const MyTestMessage& msg)
{
std::cout <<msg.symbol.GetSymbolName() << " " << msg.other << " " <<
msg.status << " " << msg.type << std::endl;
});
}
int main()
{
std::vector<MyTestMessage> my_test;
MyTestMessage msg;
msg.other = 5;
msg.symbol = Symbol("TEST");
msg.type = 5;
msg.status = 5;
my_test.push_back(msg);
Print(my_test);
my_test.push_back(msg);
Print(my_test);
return 0;
}
或者你可以在这里获取代码coliru link
这是 Visual Studio 发布版本的输出:
测试 5 5 5
测试 5 5 0
测试 5 5 5
问题是那个 0 是从哪里来的?
“修复”的两种方法:
为 MyTestMessage 添加移动构造函数,目前已被注释掉。
或注释 std::memset(other.name_, 0, sizeof(other.name_));在符号移动构造函数中。
删除 MyTestMessage 中的任何数据成员(类型、其他、状态)后,问题就消失了。
但我不相信其中任何一个都是正确的。
有什么想法我在这里做错了吗?
编辑: 编译器版本为visual studio 2017 15.6.1 并且实际上设法找到了改变输出的编译器设置: 如果“启用 IntrinsicFunctions”设置为:是 (/Oi) 问题可重现,如果设置为否,则按预期工作。
更新: 微软回应称,这确实是一个 bug,并且已经在 VS2017 15.7 Preview 1 中修复。
【问题讨论】:
-
Can't reproduce,物有所值。
-
想法:使用调试器...
-
我无法复制。请仔细检查您的 MCVE。也许您需要包含一些编译器设置。
-
罪魁祸首似乎是 Visual Studio 2017 15.6.1 上的“启用内在功能”
-
您应该自行回答这个问题,以明确这是一个错误。
标签: c++ c++11 visual-c++ move-semantics