XOR linked lists use pointer arithmetic in a way that looks suspicious to me given the changes in semantics introduced in C++17 (and discussed e.g. in Is a pointer with the right address and type still always a valid pointer since C++17?). Do they cause undefined behavior now? If so, can they be saved with launder?
EDIT:
The Wikipedia article contains just a short note about converting between pointers and integers. I tacitly assumed (and now am making it explicitly stated) that the pointers are first converted to and integer type of sufficient size to fit them, then XORing is done on the integers. The properties of XOR listed under Theory of operation thus guarantee that only integers obtained once from pointers will be converted back to them. The actual mapping from pointers to integers can be, per the standard, an arbitrary injection. I don't rely on any assumption beyond that.
Does the standard allow to use them and access the still existing objects? Before C++17? Since C++17?
It's implementation-defined, and still valid in C++17, at least for GCC. You cannot perform an xor operation between two pointers directly; you would have to go through
reinterpret_cast<std::intptr_t>. The effect of this conversion (and back) is implementation-defined.Implementation-defined means that the compiler must document what happens. What GCC provides is:
See https://gcc.gnu.org/onlinedocs/gcc/Arrays-and-pointers-implementation.html
From this description, we can conclude that:
Implications for an XOR-list
Generally, this should make XOR-lists implementable, as long as we reproduce the same pointers that we stored, and don't "rug pull" nodes while there are XORed pointers to them.
As stated in the documentation,
next"must reference the same object as the original pointer", so we can assume thatnextis now a pointer to an object, if such a pointer was originally stored inptr.However, it would be UB if we stored the XORed
nextpointer, began the lifetime of a new object wherenextpoints to, and then un-XORed the address and converted back to a pointer type.