8

Требуется получить адрес локальной переменной, и сохранить его в эту же переменную. Корректен ли такой код:

void* p = (void*) &p;

GCC переваривает нормально. Возможен ли здесь UB или нарушение strict aliasing?

А также в таком варианте:

int* p = (int*) &p;

ideone

  • фиг знает, но MSVS наверняка не даст скомпилить) – Xambey Aug 15 '16 at 14:25
  • Ну, я бы на всякий пожарный делал это не инициализацией в объявлении, а присваиванием. В остальном - "не вижу препятствий!" (с) – Harry Aug 15 '16 at 14:26
  • 1
    @Xambey а вы попробуйте - VC++ 2015 совершенно спокой но компилирует... – Harry Aug 15 '16 at 14:27
  • @Harry вот здесь было замечание, что это нарушает strict aliasing поэтому засомневался. Хотя сам не вижу его. – Vladimir Gamalyan Aug 15 '16 at 14:31
  • смешной код )) вот инетерсно в каких случаях такие трюки будут пригодны ? – ampawd Aug 16 '16 at 07:52

1 Answers1

10

Код для void* корректен т.к. тип void** приводится к void*.

Код int* p = (int*) &p; сам по себе корректен, т.к. хотя &p имеет тип int**, но его можно привести к int* через reinterpret_cast (C-style cast в данном случае).
Однако разыменовывать p нельзя, т.к. это будет нарушением правил alising: p фактически указывает на объект с типом int*, а выражение *p трактует этот объект как int.

(И конечно же результат такого reinterpret_cast нельзя разыменовать из за правил самого reinterpret_cast, но вопрос был про aliasing.)

Abyx
  • 31,143
  • strict aliasing это разве не когда два указателя разных типов на одну область памяти указывают? – Vladimir Gamalyan Aug 15 '16 at 14:41