为什么我需要声明这个函数extern。它没有它

时间:2016-01-29 03:18:19

标签: c scope extern storage-class-specifier

我是extern概念的新手。今天在工作中我遇到了大量在头文件中声明的外部函数; foo.h.在一堆乱七八糟的文件夹中,我发现了一个foo.c文件,其中包含所述函数的定义,但它没有#include foo.h。当我回到家时,我决定使用extern存储类示例。在做了一些阅读C&C"这就是我想出来的。

这是我不希望工作的东西。但确实如此。

的main.c

#include <stdio.h> 

int data;

int main()
{

  data = 6;

  printf("%d\n", getData());

  data = 8;

  printf("%d\n", getData());
  return 0;
} 

externs.c

int getData()
{
  extern int data;
  return data;
}

的bash

gcc main.c externs.c -o externs

我认为这不会起作用,因为函数在main之前并未在技术上(或至少是详细的)定义。这是否有效,因为int getData()的默认存储类是extern?如果是这样,为什么甚至打扰下面的例子(类似于我在工作中看到的)?

main2.c

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

int data;

int main()
{

  data = 6;

  printf("%d\n", getData());

  data = 8;

  printf("%d\n", getData());
  return 0;
} 

externs.h

#ifndef _EXTERNSH_
#define _EXTERNSH_

extern int getData();

#endif

externs.c

int getData()
{
  extern int data;
  return data;
}

的bash

gcc main2.c externs.c -o externs

2 个答案:

答案 0 :(得分:5)

函数隐式extern。您可以通过将其声明为static来更改此内容。

你说extern int getData();int getData();相比是多余的,但有些人认为它可以提高代码的清晰度。

请注意,自C99起,您的第一个示例就是格式错误。它在没有声明该函数的情况下调用getData。在C89中,这执行了一个隐式的int getData();声明,但是因为C99被删除了。使用编译器开关-std=c99 -pedantic来测试它。

答案 1 :(得分:4)

默认情况下,GCC版本4.x或更早版本在C89 / C90兼容模式下编译,这不需要在使用前声明函数。推断未声明的函数的返回类型为int。默认情况下,GCC 5.x或更高版本在C11兼容模式下编译,这需要在使用前声明函数 - 就像C99一样。

鉴于代码编译时没有投诉,我们可以推断您使用的是GCC 4.x。

即便如此,你也没有义务提供完整的原型,尽管你不会愚蠢。我经常用以下选项编译代码:

gcc -std=c11 -O3 -g -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes \
    -Wold-style-definition -Wold-style-declaration …

我怀疑那里有一些冗余,但是在我开始运行代码之前,这些选项会遇到很多问题。