| palm_mute ( @ 2008-03-05 12:40:00 |
| Entry tags: | c++ |
Загадка
Пришлось по долгу службы вспоминать язык программирования Ц++. До чего же быстро забываются все эти overload resolution'ы, template argument deduction'ы, one definition rule'ы, 2-phase name lookup'ы и пр. без активного использования.
Рассмотрим код единицы трансляции ниже:
#include <iostream>
template <class T>
void f()
{
std::cerr << "yo whazzup" << std::endl;
}
void g()
{
f<int>();
}
Рассмотрели? Кто может, не подглядывая в "C++ Templates: The Complete Guide" или в
Дополнение: в коде данной единицы трансляции ничего менять нельзя (кроме типа возвращаемого значения f, естественно).
з.ы. совсем не исключаю, что это все знают, а я один такой деревянный; но язык, в котором такое возможно, - это кошмар, по-моему.
Update.
Внимание, правильный ответ:
Я старался формулировать осторожно, потому надеюсь, что ни для кого не будет сюрпризом, что в загадке приведен не весь код - а именно, опущен код еще одной единицы трансляции (слово "ситуация" подразумевало такую возможность). Предположим, что код из загадки находится в файле b.cpp, а код ниже - в файле a.cpp
#include <iostream>
template <class T>
void f()
{
std::cerr << "surprise!" << std::endl;
}
template void f<int>();
void g();
int main (int argc, char* argv[])
{
g();
return 0;
}
Программа, скомпилированная командой g++ a.cpp b.cpp (g++ (GCC) 4.1.2 (Ubuntu 4.1.2-0ubuntu4)) печатает "yo whazzup" или "surprise!" в зависимости от типа возвращаемого значения шаблона функции f, определенного в b.cpp.
Я понимаю это так: в разделе 12.2.1 книги "C++ Templates: The Complete Guide" (думаю, можно найти объяснение, основываясь прямо на тексте стандарта, но мне лень) перечисляются случаи, при которых в C++ могут сосуществовать в одной программе одноименные функции. Ключевая фраза:
"Two functions can coexist in a program if they have distinct signatures. We define the signature of a function as the following information: ... Its return type, if the function is generated from a function template". Таким образом, определение шаблонов template <class T> void f() в обеих единицах трансляции нарушает one definition rule, что приводит к Undefined Behaviour. g++ имел право в этом случае залить соседей или вызвать ОМОН, но он просто вызвал ту функцию, которая ему больше понравилась.
Пусть знающие товарищи меня поправят.