Вы пробираетесь в территорию неопределенного поведения.
Если вы пишете
void* tmp = &integer;
компилятор даст вам ошибку. Если вы написали хороший код на C++ и написали
void* tmp = static_cast<void*>(&integer);
компилятор все равно даст вам ошибку. Но вы пошли вперед и использовали незащищенный бросок C-стиля, который оставил компилятору не вариант, а делать то, что вы ему сказали.
Есть несколько способов, компилятор мог бы иметь дело с этим, не в последнюю очередь из которых:
- Это может занять адрес местоположения в сегменте кода, где значение было, например,, загружается в регистр.
- Это может быть адрес аналогичный значение.
- Это может создать временное значение, нажав значение на стек, взяв адрес местоположения, а затем вытащив стек.
Вы должны смотреть на сборке производства, чтобы увидеть, какой вариант предпочитает ваш компилятор, но в конце дня: не делает это это неопределенные и это означает, что в следующий раз при обновлении ваш компилятор или построить на другой системе или изменить настройки оптимизатора, поведение может измениться.
Рассмотрим
const char h = 'h';
const char* hello = "hello";
const unsigned char num = 2 * 50 + 2 * 2; // 104 == 'h'
arg -= num; // sub 104, eax
char* ptr = (char*)(&h);
Компилятор может выбрать для хранения «ч» специально с целью «PTR», или он может выбрать, чтобы сделать «PTR» указывают на «ч» в привет. Или он может выбрать местоположение местоположения значения 104 в команде «sub 104, eax».
Да, если вы хотите достаточно хорошо стрелять в ногу, вы можете найти способ. – meagar
Я помню, что когда я это сделал (как в Delphi, так и в C), я получил «нарушение доступа». Возможно, ПК сможет проверять доступ во время выполнения, но ваша платформа отличается. – Val
Шаг указателя пустоты не нужен. И никто не упоминал о неопределенном поведении, поэтому обратите внимание, что UB - это то, что есть. – chris