考虑以下程序(受此处的 Tcl 源代码启发):
测试.h
void func(char* format, ...);
Run Code Online (Sandbox Code Playgroud)
测试.c
#include <stdio.h>
#define func funcDummy
#include "test.h"
#undef func
void func(char *format, char *arg)
{
printf(format, arg);
}
Run Code Online (Sandbox Code Playgroud)
主文件
#include "test.h"
int main(int argc, char *argv[])
{
(void) argc;
(void) argv;
func("I'm %s\n", "confused");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译时没有警告使用gcc main.c test.c -Wall -Wextra并输出“我很困惑”。
我希望看到关于存在对函数 func 的未解析引用的错误。这是怎么回事?
这是有效的,因为 C 没有损坏的名称。在 C 中,符号名称是“func”。在 C++ 中,符号名称类似于“_Zblahblah_func_blahblah_E”。C++ 将参数编码为符号名称(稍后由链接器使用)。C 没有。
test.c 定义了函数 void func(char *format, char *arg)。
编译 main.c 时,编译器看到:'void func(char* format, ...);'
然而,链接器将两者都简称为“func”。当链接器看到 main.c 中的调用时,它会将 func 的定义视为简单的“func”(该死的参数)。
碰巧的是,您在 main.c 中传递给它的 args 恰好与 func.c 中预期的那些兼容,因此它神奇地工作。
如果您将文件更改为“cpp”而不是“c”,则会出现链接器错误(因为两个原型的损坏名称将不匹配,并且会出现链接器错误)
TL;DR:C++ 支持函数重载,C 不支持。