Да, вам просто повезло :) Extern "C" - это одна языковая связь для языка C, которую должен поддерживать каждый компилятор C ++, кроме extern "C ++", который используется по умолчанию. Компиляторы могут поддерживать другие языковые ссылки. GCC, например, поддерживает extern "Java", который позволяет взаимодействовать с Java-кодом (хотя это довольно громоздко).
extern "C" сообщает компилятору, что ваша функция может вызываться кодом C. Это может, но не обязательно, включать в себя соответствующее соглашение о вызовах и соответствующее искажение имени языка C (иногда называемое «украшением») среди прочего, в зависимости от реализации. Если у вас есть статическая функция-член, соглашение о вызовах для нее - это соглашение вашего компилятора C ++. Часто они такие же, как и для компилятора C этой платформы, поэтому я сказал, что вам просто повезло. Если у вас есть C API и вы передаете указатель на функцию, лучше всегда ставьте его в функцию, объявленную с extern "C", как
extern "C" void foo() { ... }
Несмотря на то, что тип указателя на функцию не содержит спецификацию связи, а выглядит как
void(*)(void)
Связь является неотъемлемой частью типа - вы просто не можете выразить ее напрямую без typedef:
extern "C" typedef void(*extern_c_funptr_t)();
Компилятор Comeau C ++ в строгом режиме выдаст ошибку, например, если вы попытаетесь присвоить адрес указанной выше внешней функции "C" для (void(*)())
, потому что это указатель на функцию с C ++ связь.