尝试调试并理解一个似乎是移动构造函数的小问题,问题只出现在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发布版本的输出:
TEST 5 5 5
TEST 5 5 0
TEST 5 5 5
问题是0来自哪里?
两种“修复它”的方法:
为MyTestMessage添加移动构造函数,此时已注释掉。
或者评论std :: memset(other.name _,0,sizeof(other.name_));在符号移动构造函数中。
删除MyTestMessage中的任何数据成员(类型,其他,状态)后问题消失。
但我不相信其中任何一个是正确的。
我在这里做错了什么想法?
修改 编译器版本是visual studio 2017 15.6.1 实际上设法找到改变输出的编译器设置: 如果“Enable IntrinsicFunctions”设置为:Yes(/ Oi)问题是可重现的,如果设置为No,则按预期工作。
更新 微软已经做出回应,它确实是一个错误,它已经在VS2017 15.7 Preview 1中得到修复。
答案 0 :(得分:0)
代码没有错。
这似乎是VS中的一个错误。据推测已修复VS2017 15.7预览1。
答案 1 :(得分:-3)
我在这里做错了什么想法?
当您不需要时,您会使用指针。只需使用:
struct Symbol { char name[kSize]; };
你的例子中有什么。 ......但是,坦率地说,除非有充分的理由不这样做,坚持std::string
。