dar*_*ven 12 c variables linker static
我是C语言编程的新手,所以我尝试了许多不同的东西来尝试熟悉语言.
我写了以下内容:
文件q7a.h:
static int err_code = 3;
void printErrCode(void);
Run Code Online (Sandbox Code Playgroud)
文件q7a.c:
#include <stdio.h>
#include "q7a.h"
void printErrCode(void)
{
printf ("%d\n", err_code);
}
Run Code Online (Sandbox Code Playgroud)
文件q7main.c:
#include "q7a.h"
int main(void)
{
err_code = 5;
printErrCode();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
然后我在makefile中运行以下命令(我使用的是Linux操作系统)
gcc –Wall –c q7a.c –o q7a.o
gcc –Wall –c q7main.c –o q7main.o
gcc q7main.o q7a.o –o q7
Run Code Online (Sandbox Code Playgroud)
输出为3.
为什么会这样?
如果在头文件中初始化一个静态变量(实际上是任何变量),那么如果2个文件包含相同的头文件(在本例中为q7.c和q7main.c),则链接器将给出两次定义的错误相同的var?
为什么不将值5插入到静态var中(毕竟它是静态的和全局的)?
谢谢您的帮助.
Ebo*_*ike 40
static表示该变量仅在您的编译单元中使用,并且不会向链接器公开,因此如果您static int在头文件中有一个并且包含两个单独的.c文件,那么您将拥有该int的两个离散副本,很可能根本不是你想要的.
相反,您可以考虑extern int,并选择一个实际定义它的.c文件(即只是int err_code=3).
小智 6
当您将变量声明为静态变量时,它仅在文件内具有作用域,即..,它只能在文件内访问。当您在头文件中声明一个静态变量并将此头文件包含在两个 .c 文件中时,您将为两个不同的“.c”文件创建两个不同的内存
当您直接在 Main 函数中打印 err_code 时,您会看到它的值为 5 而不是 3,但是您正在调用在不同文件“q7a.c”中定义的函数 printErrCode,其中 err_code 具有不同的内存位置,其中 err_code 内存仍然是 3 并且它没有更新,这就是为什么你得到的值是 3 而不是 5。
由于创建了两个内存并且 err_code 被视为具有不同内存和不同文件范围的两个不同变量,因此您不会看到任何链接错误。
静态变量没有外部链接,这意味着不能在定义它们的翻译单元之外访问它们。因此,在您的情况下,当 q7.h 在两个翻译单元 q7a.c 和 q7main.c 中都被 #include 时......它们对应的 .o 文件中存在两个不同的副本。这就是链接器不报告错误的原因,因为在执行外部符号链接时,链接器看不到两个副本。