Để khắc phục sự cố liên kết, tôi cần ghi nhớ tạm thời. Loại tạm thời nên là loại nào? gcc than phiền rằng reinterpret_cast sau sẽ phá vỡ các quy tắc bí danh nghiêm ngặt:Cách hành vi không xác định không xác định một đối tượng từ một mảng byte trong C++ 11 (hoặc sau này) là gì?
template <typename T>
T deserialize(char *ptr) {
static_assert(std::is_trivially_copyable<T>::value, "must be trivially copyable");
alignas(T) char raw[sizeof(T)];
memcpy(raw, ptr, sizeof(T));
return *reinterpret_cast<T *>(raw);
}
(ví dụ: khi T là "dài").
Tôi không muốn xác định T vì tôi không muốn tạo T trước khi ghi đè lên.
Trong liên minh, không viết một thành viên, sau đó đọc một số khác là hành vi không xác định?
T result;
char * p = reinterpret_cast<char *>(&result); // or std::addressof(result) !
std::memcpy(p, ptr, sizeof(T)); // or std::copy!!
return result;
Không răng cưa vi phạm:
template<typename T>
T deserialize(char *ptr) {
union {
char arr[sizeof(T)];
T obj;
} u;
memcpy(u.arr, ptr, sizeof(T)); // Write to u.arr
return u.obj; // Read from u.obj, even though arr is the active member.
}
Có một số [ngũ cốc] (https://uscilab.github.io/cereal/) và đừng lo lắng về điều đó. – nwp
Tôi có [câu trả lời của luật sư ngôn ngữ về con trỏ và bí danh] (http://stackoverflow.com/a/12615861/726300), nhưng như báo trước đây là khu vực màu xám trong Tiêu chuẩn. Nó được cho là được cải thiện trong tương lai, nhưng tôi không có ý tưởng về hướng nào. Chương trình của bạn có thể được [tinh chỉnh] (http://coliru.stacked-crooked.com/a/1207492fe8779748) để theo dõi các quy tắc đối với lá thư, nhưng tôi không thể nói liệu các trình biên dịch có đồng ý hay không. Ít nhất GCC không phàn nàn nữa, nhưng điều đó có thể chỉ là do chúng tôi nhầm lẫn phân tích bí danh của nó. Đáng buồn là tôi không có thời gian để trả lời đúng. –
@LucDanton: Tôi không nghĩ rằng ngay cả ['std :: launder'] (http://en.cppreference.com/w/cpp/utility/launder) cung cấp cơ sở mà OP mong muốn. –