Я спросил вопрос здесь о том, вызывает ли получение адреса функции компиляцию упомянутой функции, в частности, в отношении ошибки замещения, не являющейся ошибкой. Самый прямой ответ на это можно найти Вот:
Неформально, объект используется odr, если его адрес взят, или ссылка привязана к нему, и функция используется odr, если выполняется вызов функции или принят его адрес. Если объект или функция используются odr, их определение должно существовать где-то в программе; нарушение этого является ошибкой во время соединения.
Но все протестированные мной компиляторы показывают, что это вполне выполнимо:
void foo(int);
auto bar = &foo;
Это не законно, не так ли? Но если нет, то почему это здание?
От [Basic.def.odr]:
Каждая программа должна содержать ровно одно определение каждой не встроенной функции или переменной, которая используется в odr
эта программа; Диагностика не требуется.
foo
используется odr, но не имеет определения (предположительно — в противном случае вопрос является спорным). Программа плохо сформирована, но поскольку диагностика не требуется, ее можно скомпилировать.
Как правило, компоновщик улавливает отсутствие определения, а не компилятор, поскольку определение может легко появиться в другом модуле перевода. Канонический пример пытается передать static const int
который не имеет определения в призыв к std::max()
или же std::min()
,
Ваш пример работает, потому что адрес никогда не используется, поэтому компоновщик никогда не ищет символ.
Если вы попытаетесь напечатать bar
связывание не удается.
void foo(int);
auto bar = &foo;
cout << (void*) bar;