静态声明m遵循非静态声明

时间:2013-06-11 10:08:23

标签: c

我正在尝试一个小例子来了解静态外部变量及其用途。静态变量属于局部范围,外部变量属于全局范围。

static5.c

#include<stdio.h>
#include "static5.h"
static int m = 25;
int main(){
 func(10);
 return 0;
}

static5.h

#include<stdio.h>
int func(val){
 extern int m;
 m = m + val;
 printf("\n value is : %d \n",m);
}

gcc static5.c static5.h

o / p:

static5.c:3: error: static declaration of m follows non-static declaration
static5.h:3: note: previous declaration of m was here

已编辑

正确的计划:

a.c:
#include<stdio.h>
#include "a1_1.h"
int main(){
 func(20);
 return 0;
}

a1.h:
static int i = 20;

a1_1.h:
#include "a1.h"
int func(val){
 extern int i;
 i = i + val;
 printf("\n i : %d \n",i);
}

这很好用。但是这被编译成一个单独的编译单元。因此能够访问静态变量。在编译单元中,我们不能通过使用extern变量来使用静态变量。

4 个答案:

答案 0 :(得分:16)

记住这一点(引用Eli Bendersky):

  
      
  • 函数内部的静态变量保持其值   调用。
  •   
  • 静态全局变量或函数仅在“看到”中   它在
  • 中声明的文件   

在您的代码中,static int m = 25;表示m范围仅限于该文件,也就是说,它仅在static5.c内可见且无处可去。

如果您想在m之外使用static5.c,请务必从变量声明中删除关键字static

有关更典型的解释以及示例,请参阅this answer by Eli Bendersky

编辑:(根据Klas的推荐) **实际范围是编译单元,而不是源文件。 编译单元是文件在预处理器步骤

之后的样子

答案 1 :(得分:16)

static有一个非常简单的逻辑。如果变量是static,则意味着它是一个全局变量,但它的范围仅限于定义它的位置(即仅在那里可见)。例如:

  • 在函数外部:全局变量,但仅在文件(实际上是编译单元)中可见
  • 在函数内部:全局变量,但仅在函数
  • 中可见
  • (C ++)一个类:全局变量,但只对类
  • 可见

现在让我们看看C11标准对staticextern(强调我的)的说法:

  

6.2.2.3

     

如果对象或函数的文件范围标识符的声明包含存储类说明符static,则标识符具有内部链接。

     

6.2.2.4

     

对于在该标识符的先前声明可见的范围内使用存储类说明符extern声明的标识符,如果先前声明指定内部或外部链接,则后面声明中的标识符与先前声明中指定的链接相同。 如果没有先前声明可见,或者如果先前声明未指定链接,则标识符具有外部链接。

     

6.2.2.7

     

如果在翻译单元中,同一标识符同时显示内部和外部链接,则行为未定义。

所以标准说首先,如果你有:

static int m;
extern int m;

然后第二个声明(使用extern)会认为第一个声明m仍然是static

但是,在任何其他情况下,如果存在具有内部和外部链接的声明,则行为未定义。这实际上只留下了一个选项:

extern int m;
static int m;

extern声明之前的static声明。 gcc足以让你在未定义的行为的情况下给你错误。

答案 2 :(得分:3)

问题与错误消息中的说明完全相同。 m被宣布为正常int,但后来被定义为static int

extern告诉编译器/链接器在全局变量表中查找变量。

static(在功能之外)告诉编译器从全局变量表中排除变量。

你看到了冲突吗?

要解决此问题,请从定义中移除static关键字,或将定义移至包含static5.h的上方。

应该注意的是,您设计文件的方式不是最佳做法。包含文件通常不包含函数。

答案 3 :(得分:2)

在声明m时删除关键字static,错误将被删除,您将能够得到50的答案.static关键字使范围限制在文件中。