Ответ 1
Мой вопрос следующий: существует ли реализация С++ связанного с XOR списка, которая не приводит к поведению undefined?
Если по "есть ли реализация" вы имеете в виду "уже написано", то я не знаю. Если вы имеете в виду "возможно ли написать одно", тогда да, но могут быть некоторые предостережения о переносимости.
Вы можете погладить свой сердечный контент, если перед тем, как начать, вы конвертируете оба указателя в uintptr_t
и сохраните этот тип в node вместо указателя. Побитовые операции с неподписанными типами никогда не приводят к поведению undefined.
Однако uintptr_t
является необязательным типом, поэтому он не является полностью переносимым. Нет требования, чтобы реализация С++ фактически имела целочисленный тип, способный представлять адрес. Если в реализации нет uintptr_t
, тогда код разрешается компилировать с помощью диагностики, и в этом случае его поведение выходит за рамки стандарта. Не уверен, считаете ли вы, что нарушение "без UB" или нет. Я имею в виду, серьезно, компилятор, который позволяет использовать код, который использует типы undefined?; -)
Чтобы избежать uintptr_t
, я думаю, что вы могли бы сделать свой бит-twiddling на массиве sizeof(node*)
unsigned chars. Указатели являются типами POD и поэтому могут быть скопированы, повернуты и искалечены при условии, что представление объекта будет восстановлено до его первоначального состояния перед использованием в качестве указателя.
Обратите также внимание, что если ваша реализация на С++ имеет сборщик мусора, тогда преобразование в целое число /xor/xor -back-again/convert-to-pointer не обязательно останавливает собираемый объект (поскольку это приводит к "небезопасный производный указатель" ). Поэтому для переносимости вы также должны убедиться, что результирующие указатели действительны. Два способа сделать это:
- наберите
declare_reachable
. - Используйте реализацию с непринужденной безопасностью указателя (это определяется реализацией, если это так, и вы можете проверить ее с помощью
get_pointer_safety()
с учетом того, что непринужденной реализации разрешено ложно утверждать, что она является строгой).
Вы можете подумать, что есть третий способ (хотя и тот, который побеждает цель связанного списка XOR, если у вас его нет):
- сохранить отдельный контейнер всех значений указателя
Это не гарантируется. Недопустимый вывод указателя недействителен, даже если он оказывается равным безопасно полученному указателю (3.7.4.3/4). Я тоже был удивлен.