gpt4 book ai didi

c - 使用共享库时的函数原型(prototype)

转载 作者:太空宇宙 更新时间:2023-11-04 07:31:37 26 4
gpt4 key购买 nike

我不确定用来描述这个问题的正确术语,但我会尽力而为。

我正在编写一个玩具程序,在 test.c 中打印 12 和 13 的阶乘:

#include <stdio.h>

int main(void)
{
printf("%ld\n", factorial(12));
printf("%ld\n", factorial(13));
return 0;
}

阶乘函数在源 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位的十进制值。但是,如果我在 test.c 的顶部插入函数原型(prototype) long factorial(int) 并重新编译,我会得到正确的结果。

$ LD_LIBRARY_PATH=. ./a.out
479001600
6227020800

这给我留下了几个问题:

  1. 如果我没有在 test.c 中指定原型(prototype),假定的返回类型是什么?这个编译器依赖吗?
  2. 没有原型(prototype),我似乎能够将任意数量的参数传递给factorial。这和这个有关吗question about C void arguments还有这个question about function prototypes
  3. 为什么链接器不抛出 undefined reference 错误?

最佳答案

从 1990 版的 C 标准开始,如果您调用没有可见声明的函数,编译器会假定它返回类型 int .所以对于 factorial() 的调用在您的主程序中,编译器很可能会解释 long它返回的值就好像它是一个int值(value)。如果longint碰巧具有相同的表示,这可能会起作用。如果longint 宽,它可能碰巧起作用,也可能失败。但是无论哪种方式,行为都是未定义的。

C 标准 (C99) 的 1999 版删除了“隐式整数”规则。调用没有可见声明的函数是约束冲突,需要编译器诊断。然后,编译器可能会拒绝该程序,或者继续编译它——但如果是这样,则行为是未定义的。

要更正此问题,您需要有一个可见的声明 factorial() 你调用它之前。最好的方法是创建一个头文件,factorial.h :

阶乘.h:

#ifndef FACTORIAL_H
#define FACTORIAL_H

long factorial(int n);

#endif

阶乘.c:

#include <stdio.h>
#include "factorial.h"

long factorial(int n)
{
printf("factorial(%d)", n);
long r = 1;
while (n > 1) r *= n--;
printf(" --> %ld\n", r);
return r;
}

ma​​in.c:

#include <stdio.h>
#include "factorial.h"

int main(void)
{
printf("%ld\n", factorial(12));
printf("%ld\n", factorial(13));
return 0;
}

请注意,如果 long,这仍然将不起作用只有 32 位,因为 13 阶乘超过 231-1。检查 LONG_MAX 的值和/或 sizeof (long)在您的系统上:

printf("LONG_MAX = %ld, sizeof (long) = %d\n", LONG_MAX, (int)sizeof (long));

考虑使用 long long而不是 long -- 或者,更好的是,int64_tuint64_t , 在 <stdint.h> 中定义.

(据我所知,您使用共享库不会影响这一切。)

关于c - 使用共享库时的函数原型(prototype),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13223646/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com