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