Вчера мы рассматривали такой код и он фейлился при линковке:
#include <algorithm>
struct foo {
static const int qwerty = 100;
};
int main() {
std::cout << std::max(0, foo::qwerty) << std::endl;
return 0;
}
Но стоит нам добавить всего лишь + к имени переменной foo::qwerty и код сразу же начнет компилироваться и выдавать ожидаемый результат.
int main() {
std::cout << std::max(0, +foo::qwerty) << std::endl;
return 0;
}Почему?
Для интов определено унарный оперетор +, который возвращает временное значение. Он не реализован в рамках обычных функций С++ и компилятор может как угодно его оптимизировать, но главное, что нам нужно знать - компилятор рассматривает это как новое rvalue значение. Которое может кастится к константной ссылке и эта операция не требует наличия определенного адреса объекта. А так как оригинальная переменная foo::qwerty теперь не odr-used(от нее больше не берут ссылку), то и компилятору не нужно больше определение. Он прекрасно видит значение инициализатора и может просто подставить на место foo::qwerty значение его инициализатора.
Прикол в том, что оптимизации компилятора могут помочь вам угомонить линкер. Даже вчерашний пример прекрасно собирается с оптимизациями. Однако это вообще не значит, что в программе все хорошо. Вы по прежнему должны определить это статическое поле, чтобы использовать переменную согласно стандарту, чтобы ее можно было корректно использовать во всех сценариях.
Focus on positive. Stay cool.
#cppcore