问题场景
C++函数带默认参数,并用 extern "C"导出为动态库,C程序能否直接调用并享受默认参数?
C++
// mylib.cpp
extern "C" void foo(int a, int b = 0) { /* ... */ }
C程序试图只传一个参数:foo(42);------ 这是错误的。
快速实验
-
编译动态库:
g++ -shared -fPIC mylib.cpp -o libmylib.so导出符号为
foo(nm -D可见),链接没问题。 -
C程序调用单参数版本,编译链接通过,但运行时崩溃,因为C编译器不会补全默认参数,调用栈/寄存器混乱。
根本原因
• extern "C"只保证符号名兼容(链接层面)。
• 默认参数是 C++编译期的特性,编译器在调用点自动补全参数,但二进制中不存在"默认值"信息。
• C编译器完全不知道默认参数,只按声明生成调用,参数数量不匹配导致未定义行为。