使用太少的参数调用隐式声明的函数:为什么没有链接器错误?
Calling implicitly declared function with too few arguments: why there is no linker error?
示例:
/* lib.c */
#include <stdio.h>
int f1(int a)
{
printf("%d\n", a);
return 0;
}
/* t3.c */
int main()
{
f1();
return 0;
}
gcc -c -o lib.o lib.c && gcc t3.c lib.o && ./a.exe
t3.c: In function 'main':
t3.c:3:2: warning: implicit declaration of function 'f1' [-Wimplicit-function-declaration]
3 | f1();
| ^~
1
clang -c -o lib.o lib.c && clang t3.c lib.o && ./a.exe
t3.c:3:2: warning: implicit declaration of function 'f1' is invalid in C99 [-Wimplicit-function-declaration]
f1();
^
1 warning generated.
1
问题:
- 为什么这甚至可以编译(即生成
a.exe
)?
- 为什么没有像
error: too few arguments to function call f1, expected 1, have 0
这样的链接器错误?
- 是否违反约束条件?
Why this even compiles (i.e. a.exe is generated)?
编译器支持向后兼容。在 C99 标准之前,可以在不提供声明的情况下调用函数。 C 编译器不会像 C++ 编译器那样为函数生成损坏的名称。
Why there is no linker error like error: too few arguments to function
call f1, expected 1, have 0?
链接器找到了外部名称 f1。所以解决了对f1的引用。链接器不检查函数的调用方式。
示例:
/* lib.c */
#include <stdio.h>
int f1(int a)
{
printf("%d\n", a);
return 0;
}
/* t3.c */
int main()
{
f1();
return 0;
}
gcc -c -o lib.o lib.c && gcc t3.c lib.o && ./a.exe
t3.c: In function 'main':
t3.c:3:2: warning: implicit declaration of function 'f1' [-Wimplicit-function-declaration]
3 | f1();
| ^~
1
clang -c -o lib.o lib.c && clang t3.c lib.o && ./a.exe
t3.c:3:2: warning: implicit declaration of function 'f1' is invalid in C99 [-Wimplicit-function-declaration]
f1();
^
1 warning generated.
1
问题:
- 为什么这甚至可以编译(即生成
a.exe
)? - 为什么没有像
error: too few arguments to function call f1, expected 1, have 0
这样的链接器错误? - 是否违反约束条件?
Why this even compiles (i.e. a.exe is generated)?
编译器支持向后兼容。在 C99 标准之前,可以在不提供声明的情况下调用函数。 C 编译器不会像 C++ 编译器那样为函数生成损坏的名称。
Why there is no linker error like error: too few arguments to function call f1, expected 1, have 0?
链接器找到了外部名称 f1。所以解决了对f1的引用。链接器不检查函数的调用方式。