在C中,如何将全局变量的范围限制为声明它的文件?

Met*_*ile 7 c scope

我是C的新手.我面前有一本书,解释了C的"文件范围",包括示例代码.但是代码只声明并初始化一个文件范围的变量 - 它不会通过尝试以非法方式访问它来验证变量的范围.所以!本着科学的精神,我构建了一个实验.

档案bar.c:

static char fileScopedVariable[] = "asdf";
Run Code Online (Sandbox Code Playgroud)

档案foo.c:

#include <stdio.h>
#include "bar.c"

main()
    {
    printf("%s\n", fileScopedVariable);
    }
Run Code Online (Sandbox Code Playgroud)

根据我的书和谷歌,呼叫printf()应该失败 - 但事实并非如此.foo.exe输出字符串"asdf"并正常终止.我非常想使用文件范围.我错过了什么?

Tyl*_*nry 15

你#included bar.c,它会导致预处理器在编译器接触之前将bar.c的内容字面地复制到foo.c中.

尝试摆脱包含,但告诉编译器编译两个文件(例如gcc foo.c bar.c)并观察它如你所愿抱怨.

编辑:我认为主要的混淆是在编译器和预处理器之间.语言规则由编译器强制执行.预处理器在编译器之前运行,并对那些以#为前缀的命令起作用.所有预处理器都是操作纯文本.它不解析代码或尝试以任何方式解释代码的含义."#include"指令非常直观 - 它告诉预处理器"在这里插入此文件的内容".这就是为什么你通常只在.h(头文件)文件上使用#include,而你只在头文件中放置函数原型和外部变量声明.否则,您将最终编译相同的函数,或多次定义相同的变量,这是不合法的.


Joh*_*itb 6

这是由于条款混淆造成的.file scope在C中没有涉及将标识符的限制链接到仅一个翻译单元.它也不意味着范围仅限于一个物理文件.相反,file scope意味着您的标识符是全局的.术语file,这里指的是从处理所有结果的文本#include,#define和其他预处理器指令.

一般而言,范围仅是在一个翻译单元内生效的概念.当涉及多个编译时,链接开始发生.

如果声明文件范围变量static,则它会给出变量内部链接,这意味着它在该转换单元之外是不可见的.

如果不对它做静态声明明确,或者如果你声明的文件范围变量extern,那么它是其他翻译单元可见:这些,如果他们宣称具有相同标识符文件范围的变量,将有标识链接到相同的变量.

在你的情况,纳入bar.cfoo.c插入的定义fileScopeVariable到翻译单元被编译.因此,它在该单元中可见.