gpt4 book ai didi

c++ - 使用 extern 的前向声明(在 C/C++ 的上下文中)

转载 作者:太空宇宙 更新时间:2023-11-04 05:51:05 25 4
gpt4 key购买 nike

我很困惑是否在 C 中使用 extern 来进行函数的前向声明。场景是每个函数都在单独的 .c/.cpp 文件中。我通过这个问题了解到 - External linkage of const in C ,如果所有都是 .c 文件,我不应该使用 extern 进行前向声明,无论该函数是否在同一文件中定义。

但是我想知道更多关于什么时候显式使用 extern 进行前向声明(我认为当被前向声明的函数用不同于调用函数的语言定义时,extern 将是必需的),以及任何注意事项意识到。

最佳答案

I think when the function being forward declared is defined in a different language than calling one, extern would be required.

我应该警告您,您的问题措辞不当。我很确定您对何时使用

感兴趣
extern "C" int foo(int);

在 C++ 中,但我不确定,我希望我没有在浪费时间。

让我们来区分编译器和链接器。我遗漏了一些细节,但不会影响您问题的答案。

编译器使用前向声明。在声明函数时,您向编译器提供了有关如何使用它的信息。您声明函数 F,当编译器遇到正在使用的 F 时,它知道该做什么。 (在 K&R 时代,在没有声明的情况下,编译器使用默认值,有时会导致搞笑的结果。所以现在它们在 C 和 C++ 中都是强制性的。)

通常函数的前向声明是函数原型(prototype):它提供参数类型。在 C 中,这不是绝对必要的。你可以写

int foo();

它告诉编译器 foo 是一个返回 int 的函数,但不是它需要什么参数。然后你有责任让这些正确,因为编译器无法检查。

extern 声明——无论是函数还是变量——通知编译器一个符号及其类型,并表示该定义将由另一个模块提供。编译器留下一个占位符供链接器稍后填充。

例如,如果您查看 getopt(3) 手册页,您会看到 optarg 被声明为 extern;它在 C 运行时库中定义,但您可以使用它,因为它已被声明。

现在我们来谈谈链接器,以及 C++ 的 extern "C"

对于链接器,模块公开符号。未声明为 static 的全局变量和函数具有外部链接,这意味着它们可以被其他模块使用。

在 C 中,函数名称和外部符号之间存在 1:1 的对应关系。名字就是符号。比如getopt(3)在C标准库libc中就有一个同名符号:

$ nm -g $(find /usr/lib/ -name libc.a) 2>/dev/null | grep 'T getopt' 
0000000000001620 T getopt
0000000000000000 T getopt_long
0000000000000040 T getopt_long_only

在 C++ 中,名称不是符号。 C++ 函数可以重载;相同的名称可以表示采用不同参数的不同函数。编译器构造一个对参数类型进行编码的符号。比较:

$ echo 'int foo(int foo) { return foo * foo; }' > a.c && cc  -c a.c && nm a.o
0000000000000000 T foo
$ echo 'int foo(int foo) { return foo * foo; }' > a.C && c++ -c a.C && nm a.o
0000000000000000 T _Z3fooi

符号名称的编码通常称为名称修改nm(1) 有一个demangling特性:

$ echo 'int foo(int foo) { return foo * foo; }' > a.C && c++ -c a.C && nm -C a.o
0000000000000000 T foo(int)

请注意,参数类型显示在名称旁边。

在 C++ 中,extern "C" 将函数声明或定义为 C 函数。这是一个定义:

$ echo 'extern "C" int foo(int foo) { return foo * foo; }' > a.C && c++ -c a.C && nm a.o
0000000000000000 T foo
  • 在声明中,它告诉编译器函数在别处定义,并使用 C 符号。

  • 在定义中,它告诉编译器发出一个 C 符号,即不要破坏名称,以便其他 C 模块可以使用该函数。

我希望这能回答您的问题。

关于c++ - 使用 extern 的前向声明(在 C/C++ 的上下文中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42171456/

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