C语言 m 的静态声明遵循非静态声明

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17041571/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 06:40:19  来源:igfitidea点击:

static declaration of m follows non-static declaration

c

提问by Angus

I am trying a small example to know about the static external variable and its uses. The static variable is of local scope and the external variable is of global scope.

我正在尝试一个小例子来了解静态外部变量及其用途。静态变量是局部作用域,外部变量是全局作用域。

static5.c

静态5.c

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

static5.h

静态5.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

gcc static5.c static5.h

o/p :

o/p :

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

EDITED

已编辑

The correct program :

正确的程序:

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);
}

This works fine perfectly fine. But this is compiled into a single compilation unit. Hence could able to access the static variable . Across the compilation unit we cannot use the static variable by using the extern variable.

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

回答by Shahbaz

statichas a very simple logic to it. If a variable is static, it means that it is a global variable, but it's scope is limited to where it is defined (i.e. only visible there). For example:

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

  • Outside a function: global variable but visible only within the file (actually, the compilation unit)
  • Inside a function: global variable but visible only within the function
  • (C++) Inside a class: global variable but visible only to the class
  • 函数外:全局变量但仅在文件内可见(实际上是编译单元)
  • 函数内部:全局变量但仅在函数内部可见
  • (C++) 类内部:全局变量但仅对类可见

Now let's see what the C11 standard says regarding staticand extern(emphasis mine):

现在让我们看看 C11 标准是怎么说的staticextern(强调我的):

6.2.2.3

If the declaration of a file scope identifier for an object or a function contains the storage-class specifier static, the identifier has internal linkage.

6.2.2.4

For an identifier declared with the storage-class specifier externin a scope in which a prior declaration of that identifier is visible, if the prior declaration specifies internal or external linkage, the linkage of the identifier at the later declaration is the same as the linkage specified at the prior declaration.If no prior declaration is visible, or if the prior declaration specifies no linkage, then the identifier has external linkage.

6.2.2.7

If, within a translation unit, the same identifier appears with both internal and external linkage, the behavior is undefined.

6.2.2.3

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

6.2.2.4

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

6.2.2.7

如果在翻译单元内,相同的标识符出现在内部和外部链接中,则行为未定义。

So the standard says that first, if you have:

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

static int m;
extern int m;

then the second declaration (with extern) would regard the first one and in the end mwould still be static.

那么第二个声明 (with extern) 将视为第一个声明,最后m仍然是static.

However, in any other case, if there are declarations with both internal and external linkage, the behavior is undefined. This actually leaves us with only one option:

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

extern int m;
static int m;

i.e., externdeclaration before staticdeclaration. gcc was nice enough to give you error in this case of undefined behavior.

extern声明前static声明。在这种未定义行为的情况下,gcc 非常好,可以给你错误。

回答by NlightNFotis

Remember this (quoting Eli Bendersky):

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

  • A static variable inside a function keeps its value between invocations.
  • A static global variable or a function is "seen" only in the file it's declared in
  • 函数内的静态变量在调用之间保持其值。
  • 静态全局变量或函数仅在其声明的文件中“可见”

In your code, static int m = 25;means that m's scope is limited only to that file, that is, it is only visible inside static5.cand nowhere else.

在您的代码中,static int m = 25;意味着 thatm范围仅限于该文件,也就是说,它仅在内部可见static5.c,在其他任何地方都不可见。

If you would like to make use of moutside of static5.cmake sure to remove the keyword staticfrom the declaration of the variable.

如果您想使用m外部,请static5.c确保static从变量声明中删除关键字。

For a more canonical explanation, along with an example, see this answer by Eli Bendersky

有关更规范的解释以及示例,请参阅Eli Bendersky 的这个答案

EDIT: (according to Klas' recommendation)**The actual scope is a compilation unit, not the source file. The compilation unit is the way the file looks after the preprocessor step

编辑:(根据 Klas 的建议)**实际范围是一个编译单元,而不是源文件。编译单元是文件在预处理器步骤之后的方式

回答by Klas Lindb?ck

The problem is exactly as stated in the error message. mis declared a normal intbut is later defined as a static int.

问题与错误消息中所述完全相同。m被声明为正常,int但后来被定义为static int.

externtells the compiler/linker to look for the variable in the global table of variables.

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

static(outside a functon) tells the compiler to exclude the variable from the global table of variables.

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

Do you see the conflict?

你看到冲突了吗?

To fix the problem, either remove the statickeyword from the definition or move the definition above the inclusion of static5.h.

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

It should be noted that the way you have designed your files is not considered best practice. Include files don't usually contain functions.

应该注意的是,您设计文件的方式不被视为最佳实践。包含文件通常不包含函数。

回答by Santhosh Pai

remove the keyword static while declaring m and the errors will be removed and you will be able to get the answer as 50. The static keyword makes the scope to restrict within the file.

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