static 关键字会影响作用域吗?

Does the static keyword affect scope?

在 C89 中,static 关键字是否影响作用域?

我的软件负责人告诉我:

"A variable marked static at the top of a file doesn't technically have global scope any longer. Static is a scope qualifier as well as a storage keyword. Scope is a concept that covers visibility of symbols, though visibility is automatically compiled to have storage duration intrinsically tied in by almost all languages. By this I mean that you can't name a scope that doesn't also define the storage duration in C/C++. Expression scope is not user defined and in C/C++ covered by l-param and r-param Block scope is fully lexical in C/C++ by user defined bodies Function scope is fully lexical in C/C++ by user defined bodies and declarations File scope does not technically exist in C/C++, as globals and module scope take over depending upon lexicon Module scope is keyword defined using static in C/C++, other scope lexicon change the rules for access but the visibility remains module based Global scope is the default in C/C++ when no other scope applies and is lexically controlled by the extern keyword The issue is that static is not JUST a scope qualifier as a keyword. It is a scope qualifier AND a memory keyword."

我很困惑。我一直认为 static 与翻译单元之间的可见性和变量的存储持续时间有关。两者都与范围无关。不是这样吗? C++ 中的 static/scope 关系是否不同?

你的线人很困惑。 static 对范围没有任何影响。

文件范围用词不当,因为您可以使用#include 指令或其他假设的依赖于实现的工具来构建多文件翻译单元。全局范围也是用词不当,因为一个程序可以由多个翻译单元组成。模块仍然不是语言的一部分。

static 可以影响链接,但这与作用域是不同的概念。

C11 标准的第 6.2.1 节定义了 "scope" 的含义:

For each different entity that an identifier designates, the identifier is visible (i.e., can be used) only within a region of program text called its scope. Different entities designated by the same identifier either have different scopes, or are in different name spaces. There are four kinds of scopes: function, file, block, and function prototype. (A function prototype is a declaration of a function that declares the types of its parameters.)

C89/90 规范的第 3.1.2.1 节几乎相同:

An identifier is visible (i.e., can be used) only within a region of program text called its scope . There are four kinds of scopes: function, file, block, and function prototype. (A function prototype is a declaration of a function that declares the types of its parameters.)

所以 没有 全局 作用域,至少就 C 标准而言是这样。在任何函数或块之外定义的标识符具有 file 范围,static 的存在与否对此没有影响,仅影响符号的 链接,这是完全不同的东西(但您的领导可能将其与术语 "scope" 混淆或混淆)。

A variable marked static at the top of a file doesn't technically have global scope any longer.

"Global scope" 不是 C 中存在的概念。正确的术语是 文件范围 。在 C++ 中,存在一个类似的概念,称为 全局命名空间 。好像加班的人把这两个词结合起来了。

Static is a scope qualifier as well as a storage keyword.

static 不是范围限定符,它是存储-class 说明符。 static 会影响 link 年龄和存储期限,但不会影响范围。

Scope is a concept that covers visibility of symbols, though visibility is automatically compiled to have storage duration intrinsically tied in by almost all languages.

范围与符号的可见性无关(在 link 意义上)。链接确实如此(因此它被称为 linkage)。第二个条款是胡言乱语。

By this I mean that you can't name a scope that doesn't also define the storage duration in C/C++.

这句话也说不通。考虑块范围内的局部静态变量。它具有静态存储持续时间,即使块作用域定义了自动存储变量。

Expression scope is not user defined and in C/C++ covered by l-param and r-param

"Expression scope" 没有意义。 "l-param" 和 "r-param 也是无意义的词。

跳过关于 "lexical" 和 "modules" 的部分,因为它没有意义。

The issue is that static is not JUST a scope qualifier as a keyword. It is a scope qualifier AND a memory keyword.

同样,static 与作用域或内存无关。使用这种过于简化的解释基本上忽略了存储持续时间、范围和初始化的所有其他方面,因此它根本行不通。

关键字 static 在 C 中有多种用途。例如,在顶部的 C 源文件中,您可能有:

#include <stdio.h>
//  .. other includes and comments and stuff

int  globallyVisibleInt = 0;    // a variable that other compilation units can see
static int fileVisibleInt = 0;  // a variable visible in the file from this point

变量 fileVisibleInt 在应用程序加载时创建和初始化,但是如果您尝试从其他编译单元访问它,您会从 link 错误尝试 link.

您还可以在函数中使用 static 来创建一个将存在并保持状态的变量。

int myFunc (int k)
{
    static int mySavedInt = 0;   // create and initialize a permanent int variable

    if (k > 10) {
        mySavedInt = k;  // use the variable to save a value for the next time function is called
    } else if (mySavedInt > 22) {
        // do some stuff
    }
}

static 变量对文件中的其他源可见的点是它在源文件中出现的点,它的可见性受各种范围规则的约束。例如,函数中定义的 static 仅在该函数中可见,或者如果 static 用于其他更小的范围,例如 iffor那么它是一个永久变量,只在该范围内可见。

有各种常用的短语,但在技术上不一定准确,也不一定符合标准。例如短语 "global scope" 对我来说意味着这个东西在编译单元之外是可见的。通过 "module" 我将承担职能。对于大多数日常活动,语言松散就可以了。

在 C++ 中,static 可能会有很大的不同,具体取决于您是否使用 C++ 构造(例如 class 和使用 static 作为方法和成员的限定符,或者如果您正在以旧的 C 方式使用它。

另请参阅:

File Scope and Global Scope: C & C++.

Why file scope static variables have to be zero-initialized?

Dr. Dobbs: Scope Regions in C++.