Строгие указатель псевдоним: доступ к «нестабильному» указателю/ссылке?

StackOverflow https://stackoverflow.com/questions/2981827

Вопрос

В пятках конкретная проблема, Самосексуал и комментарии к нему, я хотел бы понять, является ли это правильным решением, обходным пути/взломом или просто неправильно.

В частности, я переписал код:

T x = ...;
if (*reinterpret_cast <int*> (&x) == 0)
  ...

В качестве:

T x = ...;
if (*reinterpret_cast <volatile int*> (&x) == 0)
  ...

с volatile квалификатор к указателю.

Давайте просто предположим, что лечение T в качестве int В моей ситуации имеет смысл. Доступ через volatile Справочная задача решить проблему с псевдонимом?

Для ссылки, из спецификации:

Примечание: летучая часть является намеком на реализацию, чтобы избежать агрессивной оптимизации с участием объекта, поскольку значение объекта может быть изменено посредством не обнаруженной реализацией. См. 1.9 для подробной семантики. В целом, семантика летучих, предназначенная для того, чтобы быть одинаковой в C ++, поскольку они находятся в C. - Конечная нота

РЕДАКТИРОВАТЬ:

Приведенный выше код действительно решил мою проблему, по крайней мере, на GCC 4.5.

Это было полезно?

Решение

Волатильный не может помочь вам избежать неопределенного поведения здесь. Так что, если это работает для вас с GCC, это удача.

Давайте предположим, что T - стручок. Тогда правильный способ сделать это

T x = …;
int i;
memcpy(&i,&x,sizeof i);
if (i==0)
  …

Там! Нет проблем с строгим псевдонимом и нет проблемы с выравниванием памяти. GCC даже обрабатывает Memcpy как внутреннюю функцию (в этом случае не вставлен вызов функции).

Другие советы

Волатильный не может помочь вам избежать неопределенного поведения здесь.

Ну, все, что касается volatile несколько неясно в стандарте. Я в основном согласился с вашим ответом, но теперь я хотел бы немного не согласиться.

Чтобы понять, что volatile означает, что стандарт не ясен для большинства людей, в частности, некоторых писателей компилятора. Лучше думать:когда используешь volatile (и только когда), C/C ++ - это в значительной степени сборка высокого уровня.

При написании в volatile lvalue, компилятор выпустит магазин или несколько магазинов, если его недостаточно (volatile не подразумевает атомный).

При написании в volatile LVALUE, компилятор выпустит нагрузку или несколько нагрузков, если его недостаточно.

Конечно, там, где нет явной нагрузки или хранилища, компилятор просто выпустит инструкции, которые подразумевают нагрузку или хранилище.

Sellibitze дал лучшее решение: использовать memcpy для переосмысления.

Но если все доступ к области памяти сделаны с volatile Lvalues, Совершенно очевидно, что правила строгого псевдонирования не применяются. Анкет Это ответ на ваш вопрос.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top