Почему некоторые компиляторы c ++ позволяют вам использовать адрес литерала?
Вопрос
Компилятор C ++, который я не буду называть, позволяет вам использовать адрес литерала, int * p = &42;
Очевидно, что 42 - это r-значение, и большинство компиляторов отказываются это делать.
Почему компилятор допускает это?Что ты мог бы с этим сделать, кроме как выстрелить себе в ногу?
Решение
Что, если вам нужен указатель на целое число со значением 42?:)
Ссылки на C ++ очень похожи на указатели с автоматическим разыменованием.Можно создать постоянную ссылку на литерал, например, так:
const int &x = 42;
Это фактически требует, чтобы компилятор инициализировал указатель адресом целого числа со значением 42, как вы могли бы впоследствии сделать это:
const int *y = &x;
Объедините это с тем фактом, что компиляторам необходимо иметь логику, чтобы различать значение, адрес которого не был принят, и то, адрес которого был принят, поэтому он знает, что нужно сохранить его в памяти.Первому не обязательно иметь ячейку памяти, так как она может быть полностью временной и храниться в регистре, или же она может быть устранена путем оптимизации.Использование адреса значения потенциально вводит псевдоним, который компилятор не может отследить, и препятствует оптимизации.Итак, применяя &
оператор может принудительно ввести значение, каким бы оно ни было, в память.
Итак, возможно, вы обнаружили ошибку, которая объединила эти два эффекта.
Другие советы
Потому что 42 - это ответ на вопрос о жизни, Вселенной и всем остальном.Когда его спрашивают о его адресе, это сам ответ.
Язык слегка (ни в коем случае не полностью) за щекой:
Я бы сказал, что в коде приложения C ++ использование адреса целого числа, будь то lvalue или rvalue, почти всегда является ошибкой.Даже использование целых чисел для выполнения чего-либо гораздо большего, чем управление циклами или подсчет, вероятно, является ошибкой проектирования, и если вам нужно передать целое число функции, которая может его изменить, используйте ссылку.
Нашел что-то, связанное со ссылками на rvalue в C ++ 0x -- move семантика http://www.artima.com/cppsource/rvalue.html
Это фактически требует, чтобы компилятор инициализировал указатель адресом целого числа со значением 42
Тогда почему в некоторых компиляторах мы не можем использовать адрес литерала непосредственно ?
int* ptr = &10;
Ссылка:
int& ref = 10;
однако это почти то же самое, что указатель...