extern 关键字对 C 函数的影响 [英] Effects of the extern keyword on C functions

查看:39
本文介绍了extern 关键字对 C 函数的影响的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 C 中,我没有注意到在函数声明之前使用的 extern 关键字有任何影响.起初,我认为在单个文件中定义 extern int f();强制您在文件范围之外实现它.但是我发现两者都是:

In C, I did not notice any effect of the extern keyword used before function declaration. At first, I thought that when defining extern int f(); in a single file forces you to implement it outside of the file's scope. However I found out that both:

extern int f();
int f() {return 0;}

extern int f() {return 0;}

编译就好了,没有来自 gcc 的警告.我使用了 gcc -Wall -ansi;它甚至不接受 // 注释.

compile just fine, with no warnings from gcc. I used gcc -Wall -ansi; it wouldn't even accept // comments.

在函数定义之前使用extern有什么影响吗?或者它只是一个可选的关键字,对函数没有副作用.

Are there any effects for using extern before function definitions? Or is it just an optional keyword with no side effects for functions.

在后一种情况下,我不明白为什么标准设计者选择用多余的关键字乱扔语法.

In the latter case I don't understand why did the standard designers chose to litter the grammar with superfluous keywords.

澄清一下,我知道在变量中有 extern 的用法,但我只在 中询问 extern功能.

To clarify, I know there's usage for extern in variables, but I'm only asking about extern in functions.

推荐答案

我们有两个文件,foo.c 和 bar.c.

We have two files, foo.c and bar.c.

这里是 foo.c

#include <stdio.h>

volatile unsigned int stop_now = 0;
extern void bar_function(void);

int main(void)
{
  while (1) {
     bar_function();
     stop_now = 1;
  }
  return 0;
}

现在,这里是 bar.c

Now, here is bar.c

#include <stdio.h>

extern volatile unsigned int stop_now;

void bar_function(void)
{
   if (! stop_now) {
      printf("Hello, world!
");
      sleep(30);
   }
}

如您所见,我们在 foo.c 和 bar.c 之间没有共享头文件,但是 bar.c 在链接时需要在 foo.c 中声明一些东西,而 foo.c 在链接时需要来自 bar.c 的函数链接.

As you can see, we have no shared header between foo.c and bar.c , however bar.c needs something declared in foo.c when it's linked, and foo.c needs a function from bar.c when it's linked.

通过使用extern",您告诉编译器在链接时将找到(非静态)后面的任何内容;不要在当前通行证中为它保留任何东西,因为稍后会遇到它.在这方面,函数和变量被同等对待.

如果您需要在模块之间共享一些全局并且不想在头中放置/初始化它,这将非常有用.

It's very useful if you need to share some global between modules and don't want to put / initialize it in a header.

从技术上讲,库公共头文件中的每个函数都是extern",但是根据编译器的不同,将它们标记为这样的好处很少甚至没有好处.大多数编译器可以自己解决这个问题.如您所见,这些函数实际上是在别处定义的.

Technically, every function in a library public header is 'extern', however labeling them as such has very little to no benefit, depending on the compiler. Most compilers can figure that out on their own. As you see, those functions are actually defined somewhere else.

在上面的例子中,main() 只会打印一次 hello world,但会继续输入 bar_function().还要注意, bar_function() 在这个例子中不会返回(因为它只是一个简单的例子).想象一下,如果这看起来不够实用,那么在处理信号时会修改 stop_now(因此,不稳定).

In the above example, main() would print hello world only once, but continue to enter bar_function(). Also note, bar_function() is not going to return in this example (since it's just a simple example). Just imagine stop_now being modified when a signal is serviced (hence, volatile) if this doesn't seem practical enough.

外部对象对于信号处理程序、不想放入头文件或结构体的互斥锁等非常有用.大多数编译器会进行优化以确保它们不会为外部对象保留任何内存,因为他们知道他们将在定义对象的模块中保留它.然而,再一次,在对公共函数进行原型设计时,用现代编译器指定它几乎没有意义.

Externs are very useful for things like signal handlers, a mutex that you don't want to put in a header or structure, etc. Most compilers will optimize to ensure that they don't reserve any memory for external objects, since they know they'll be reserving it in the module where the object is defined. However, again, there's little point in specifying it with modern compilers when prototyping public functions.

希望有帮助:)

这篇关于extern 关键字对 C 函数的影响的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆