+ 2

Is it okay to use a C++ union like this?

I’ve provided the following code snippet. I would use this to capture the state of an object. For instance, it could be useful in an undo/redo algorithm. Is this okay to do? Are there better alternatives? https://code.sololearn.com/c5fCcr65K3sq/?ref=app

8th Jan 2022, 3:22 AM
nspaceLB_
nspaceLB_ - avatar
3 Answers
+ 1
> Is this okay to do? No. This statement in particular: cout << "Buffer Data:\t" << buf.data << "\n"; is Undefined Behavior ( https://en.cppreference.com/w/cpp/language/ub ) > It's undefined behavior to read from the member of the union that wasn't most recently written. - From https://en.cppreference.com/w/cpp/language/union > Are there better alternatives? To what? a union? Yes. Use `std::variant` ( https://en.cppreference.com/w/cpp/utility/variant ), think of it as the C++ version of a union. But, I'm not sure why is a union needed in the provided example? Why can't the code simply be: template <typename T> struct Buffer { T value; std::string data; // or std::array, or std::vector, or whatever }; As for implementing an undo/redo system, the Command Pattern ( https://en.wikipedia.org/wiki/Command_pattern ) solves that problem. A practical example can be found here: https://codereview.stackexchange.com/a/203678
8th Jan 2022, 10:16 PM
Isho
Isho - avatar
0
Isho Thank you for your answer, I can see why that is undefined behavior. The reason I made it a char array, instead of a string or anything else, is to get the actual bytes of the T value. It’s not a normal use of a union, but I was just curious.
9th Jan 2022, 5:58 PM
nspaceLB_
nspaceLB_ - avatar
0
Note that 'std::string' doesn't *have to be* a "string" (a human readable array of characters). > The class is dependent neither on the character type nor on the nature of operations on that type. - https://en.cppreference.com/w/cpp/string/basic_string You can use 'std::string' however you like, as long as the elements stored within are 'char's (std::string is an instantiation of std::basic_string<char>). An example of how std::string is used to store raw bytes instead of human-readable strings is Google's Protobuf library ( https://github.com/protocolbuffers/protobuf ). They use std::string as a "convenient container" for the serialized message objects, nothing more. Another way to store raw bytes is a 'std::vector<uint8_t>' (assuming a byte is an 8-bit value on the target platform).
9th Jan 2022, 6:26 PM
Isho
Isho - avatar