Как интегральное выражение константы, компилятор имеет полное право использовать постоянную фальцовку, чтобы удалить ее из программы. Это неверно, если вы берете его адрес. Кроме того, современный оптимизирующий компилятор может использовать LTO, inlining и постоянную фальцовку, чтобы сделать то же самое с c3 и c4, если это возможно.
Если вы не берете адрес переменной, компилятор не обязан выделять его, если он может генерировать код с эквивалентными результатами в соответствии с правилом as-if.
Редактировать: Постоянное свертывание - это то, где компилятор вычисляет выражения во время компиляции, а не во время выполнения. Например, вы можете законно делать int x[3 + 4];
, где 3 + 4
оценивается во время компиляции. Некоторые примеры, особенно те, которые связаны с МКО, стандартизированы, но реализация может выполнять больше, если это возможно. LTO - это оптимизация времени связи, когда компилятор выполняет оптимизацию между единицами перевода, когда они связаны друг с другом.
Это означает, что компилятор может вставлять тело my_f
, а затем (в зависимости от тела) константу складывать, чтобы сделать c3
постоянным выражением, а затем постоянно складывать его туда, где он используется, и не выделять его. Для c4
LTO может давать значение c4
в качестве постоянного выражения, и в этом случае он может быть также сложен и удален.
В C++ 11 есть функции constexpr
, которые позволяют сделать еще многое в этой области.
Что случилось с 'c2'? –