Рассмотрим следующий код:
Код: Выделить всё
struct V2
{
float x;
float y;
float& f()
{
// If significant, substitute char* or unsigned char* for std::byte
std::byte* self = reinterpret_cast(this); // (1)
std::byte* rep_y = self + offsetof(V2, y); // (2)
float* ptr_y = reinterpret_cast(rep_y); // (3)
return *ptr_y; // (4)
}
};
Фиксация итерации по представлению объекта, по-видимому, является основной мотивацией P1839, так что (2) больше не является UB. Это обязательно требует введения формулировок вокруг вложенности и подобъектов, и именно на этом этапе я обнаруживаю, что недостаточно хорошо разбираюсь в стандарте/его терминологии, чтобы сделать вывод, является ли f , реализованный выше, действителен.
Я знаю, что P1839 включает следующую сноску, но, похоже, речь идет о случаях, когда смещения применяются вне текущих ограничений достижимости, чего здесь нет?
Эти ограничения, основанные на достижимости, ограничивают совместимость между C и C++, особенно когда приходит к коду C, который использует offsetof для реализации навязчивых структур данных. Готовится отдельный документ, в котором предлагается снять эти ограничения. Такое направление вызывает дополнительные трудности спецификации, которые здесь не обсуждаются.
Во-первых, правильно ли я понимаю, что в случае отсутствия смещения говоря, что именно точка взаимного преобразования указателей «один является объектным представлением другого или его первым элементом», которая позволяет переинтерпретировать приведение между T* этого< /code>, представление его объекта как (скажем) std::byte*, а затем обратно в T* (с доступностью значений)?
Следовательно, или иначе, может ли указатель Rep_y, полученный с помощью (2), интерпретироваться как первый элемент объектного представления y и, следовательно, разрешать доступ к значению y через указатель с соответствующим преобразованием (3)? Исходя из вышеизложенного, это было бы так, если бы оно изначально было получено через &y, но сохраняется ли это при формировании из объектного представления V2? Почему/почему бы и нет?
Если технически это не (первый элемент) объектное представление y, или если есть какой-то другой ключевой момент, который я пропустил, сделайте изменения в определении std::launder означают, что последующая отмывка даст правильный результат? Грубо говоря, он указывает на объект с плавающей запятой, доступный из исходного указателя, так будет ли это работать? Есть ли какие-либо сложности из-за того, что мы создали указатель на (часть) представления объекта, а не указатель на предполагаемый объект (или подобъект)?
Наконец, если ничего из этого не выполняется, существует ли какой-либо код, подобный этому, который либо действителен, либо предназначен для разрешения (аналогично циклу проверки представления объекта P1839)?
Подробнее здесь: https://stackoverflow.com/questions/791 ... ject-repre
Мобильная версия