Не нарушает ли приведение к несвязанному ссылочному типу строгое правило наложения имен? - PullRequest
2 голосов
/ 10 октября 2019

Строгое правило псевдонимов гласит:

Если программа пытается получить доступ к сохраненному значению объекта через glvalue другого, чем один из следующих типов, поведение не определено:

- динамический тип объекта,

- cv-квалифицированная версия динамического типа объекта,

- тип, подобный (как определено в 4.4) динамическому типуобъект,

- тип, который является типом со знаком или без знака, соответствующим динамическому типу объекта,

- тип, который является типом со знаком или без знака, соответствующим квалифицированному cvверсия динамического типа объекта,

- агрегатный или объединенный тип, который включает один из вышеупомянутых типов среди своих элементов или нестатических элементов данных (включая, рекурсивно, элемент или нестатический элемент данныхсубагрегированный или содержащий объединение)

Мне интересно, если следующая программа уже содержит неопределенное поведение и есть лиэто «доступ к сохраненному значению»:

#include <cstdint>

    void foo() {
        std::int32_t i = 1;
        float f = 1.0f;

        std::int32_t& r = reinterpret_cast<std::int32_t&>(f);

        std::int32_t* p = reinterpret_cast<std::int32_t*>(&f);
    }

Из того, что я вижу, приведение указателя с плавающей запятой к ссылке int эквивалентно `* reinterpret_cast (& x):

Выражение glvalue типа T1 может быть приведено к типу «ссылка на T2», если выражение типа «указатель на T1» может быть явно преобразовано в тип «указатель на T2» с помощью reinterpret_cast. Результат относится ктот же объект, что и у источника glvalue, но с указанным типом. [Примечание: то есть для l-значений эталонное приведение reinterpret_cast (x) имеет тот же эффект, что и преобразование * reinterpret_cast (& x) со встроенными операторами & и * (и аналогично для reinterpret_cast (x)). - конец примечания]

Для указателей reinterpret_cast сводится к преобразованию в void *, а затем к целевому типу:

Указатель объекта может быть явно преобразован в объектуказатель другого типа.72 Когда значение типа указателя объекта преобразуется в тип указателя объекта «указатель на cv T», результатом является static_cast (static_cast (v)).

семантика двух статических приведений определяется как:

Значение типа «указатель на пустоту cv1» может быть преобразовано в значение типа «указатель на cv2 T», где T - тип объектаи cv2 - это та же квалификация cv, что и cv1 или более высокая квалификация, чем cv1. Значение нулевого указателя преобразуется в значение нулевого указателя типа назначения. Если исходное значение указателя представляет адрес A байта в памяти, и A удовлетворяет требованию выравнивания T, то результирующее значение указателя представляет тот же адрес, что и исходное значение указателя, то есть A. Результат любого другого такого указателяпреобразование не указано.

Поскольку int32_t и float имеют одинаковый размер и выравнивание, я должен получить новый указатель, указывающий на тот же адрес. Что мне интересно, так это если

референтное приведение reinterpret_cast (x) имеет тот же эффект, что и преобразование * reinterpret_cast (& x) со встроенными операторами & и * *

уже представляет собой доступ к сохраненному значению или, если это необходимо сделать где-то позже, чтобы нарушить правило строгого наложения имен.

1 Ответ

2 голосов
/ 10 октября 2019

Выполненные вами касты не являются доступом к объектам i или f.

3.1 доступ [defns.access]

«действие времени выполнения» для чтения или изменения значения объекта

Поскольку ваша программа не пытается выполнить вышеизложенное, она не нарушает строгие псевдонимы. Однако попытка использовать указателей / ссылок для чтения или записи будет нарушением. Так что это тонкая грань на шаг. Но простое получение ссылок / указателей не противоречит первому указанному вами абзацу. Приведение к несвязанным типам ссылок / указателей касается только идентификатора / адреса объекта, а не его значения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...