我不确定用来描述这个问题的正确术语,但我会尽力而为。
我正在编写一个玩具程序,在 test.c 中打印 12 和 13 的阶乘:
#include <stdio.h>
int main(void)
{
printf("%ld\n", factorial(12));
printf("%ld\n", factorial(13));
return 0;
}
阶乘函数在与 source fact.c 的共享库中定义
long factorial(int n)
{
long r = 1;
while (n > 1) r *= n--;
return r;
}
我正在使用以下命令编译共享库和我的程序:
$ gcc -shared -fPIC -o libfact.so fact.c
$ gcc -L. -lfact test.c
我在 x86-64 上,所以我希望factorial(13)
(13! = 6227020800) 不会溢出 64 位长度。但是,我得到了一个奇怪的结果。
$ LD_LIBRARY_PATH=. ./a.out
479001600
1932053504
这里,1932053504 恰好是正确结果的低 32 位的十进制值。但是,如果我long factorial(int)
在 test.c 的顶部插入函数原型并重新编译,我会得到正确的结果。
$ LD_LIBRARY_PATH=. ./a.out
479001600
6227020800
这给我留下了几个问题:
- 如果我没有在 test.c 中指定原型,假定的返回类型是什么?这个编译器依赖吗?
- 如果没有原型,我似乎可以将任意数量的参数传递给
factorial
. 这与关于 C void arguments的问题和关于函数原型的问题有关吗? - 为什么链接器不抛出未定义的引用错误?