Директива extern "C" и перегруженные функции *
В разделе 7.7 мы видели, что директиву связывания extern "C" можно использовать в программе на C++ для того, чтобы указать, что некоторый объект находится в части, написанной на языке C. Как эта директива влияет на объявления перегруженных функций? Могут ли в одном и том же множестве находиться функции, написанные как на C++, так и на C?
В директиве связывания разрешается задать только одну из множества перегруженных функций. Например, следующая программа некорректна:
// ошибка: для двух перегруженных функций указана директива extern "C"
extern "C" void print( const char* );
extern "C" void print( int );
Приведенный ниже пример перегруженной функции calc() иллюстрирует типичное применение директивы extern "C":
class SmallInt ( /* ... */ );
class BigNum ( /* ... */ );
// написанная на C функция может быть вызвана как из программы,
// написанной на C, так и из программы, написанной на C++.
// функции C++ обрабатывают параметры, являющиеся классами
extern "C" double calc( double );
extern SmallInt calc( const SmallInt& );
extern BigNum calc( const BigNum& );
Написанная на C функция calc() может быть вызвана как из C, так и из программы на C++. Остальные две функции принимают в качестве параметра класс и, следовательно, их допустимо использовать только в программе на C++. Порядок следования объявлений несуществен.
Директива связывания не имеет значения при решении, какую функцию вызывать; важны только типы параметров. Выбирается та функция, которая лучше всего соответствует типам переданных аргументов:
Smallint si = 8;
int main() {
calc( 34 ); // вызывается C-функция calc( double )
calc( si ); // вызывается функция C++ calc( const SmallInt & )
// ...
return 0;
}