gcc/clang:错误:<function_name> 的类型冲突:为什么函数名称很重要?

Pav*_*kin 2 c gcc diagnostics compiler-errors clang

示例代码(t987.c):

\n
void *NAME();\nvoid *NAME(void *, int, unsigned);\n
Run Code Online (Sandbox Code Playgroud)\n

调用:

\n
$ gcc t987.c -c -DNAME=memset1\n<nothing>\n\n$ gcc t987.c -c -DNAME=memset\n<command-line>: error: conflicting types for \xe2\x80\x98memset\xe2\x80\x99; have \xe2\x80\x98void *(void *, int,  unsigned int)\xe2\x80\x99\nt987.c:2:7: note: in expansion of macro \xe2\x80\x98NAME\xe2\x80\x99\n    2 | void *NAME(void *, int, unsigned);\n      |       ^~~~\n<command-line>: note: previous declaration of \xe2\x80\x98memset\xe2\x80\x99 with type \xe2\x80\x98void *(void *, int,  long unsigned int)\xe2\x80\x99\nt987.c:1:7: note: in expansion of macro \xe2\x80\x98NAME\xe2\x80\x99\n    1 | void *NAME();\n\n# clang: the same behavior\n
Run Code Online (Sandbox Code Playgroud)\n

问题:为什么函数名称很重要?

\n

dbu*_*ush 6

没有其他定义或声明memset1。所以这两个声明是兼容的:

void *memset1();
void *memset1(void *, int, unsigned);
Run Code Online (Sandbox Code Playgroud)

因为第一个说参数的数量和类型未知。

然而,这给你带来了一个问题:

void *memset();
void *memset(void *, int, unsigned);
Run Code Online (Sandbox Code Playgroud)

因为memset是由 C 标准定义的,因此被视为实现的一部分,所以它也在内部声明为:

void *memset(void *, int,  long unsigned int)
Run Code Online (Sandbox Code Playgroud)

这与你的第二个声明相冲突。