在标头中声明结构使其成为全局结构

时间:2012-09-28 16:45:12

标签: c header struct global

有三个文件: source1.c source2.c header.h

这两个源文件包含标题。

这是标题的代码:

struct
{
    int a;
    int b
} x;

现在发生的是结构变为全局,两个源文件现在共享名为x的结构。为什么会这样?

我知道如果您编写以下代码,它将生成两个全局变量。每个源文件一个。 (他们不共享全局变量)

int x = 0;

最后一段代码对我来说很有意义,但我真的不理解带结构的代码..

编辑:
嗯,这里的每个人都认为我应该得到链接器错误。我目前的代码是针对嵌入式系统(nxtOSEK)。我稍后会尝试将它转换为常规的C程序。

EDITEDIT:
我回来了常规C中的例子。正如你所看到的那样,不仅可以使用结构,还可以使用常规变量。

source1.c

#include "header.h"

int main(void)
{
    f();
    x = 1;
    f();
}

source2.c

#include "header.h"

void f()
{
    printf("source2: %i\n", x);
}

header.h

#include <stdio.h>

int x;

输出

source2: 0
source2: 1

请注意,不得声明x才能使其正常工作,否则会产生链接器错误,就像此处所说的每个人一样。 (我不知道为什么它与嵌入式系统一起工作..)

看起来我也误读了Eric Postpischil的回答,看起来是正确的。

2 个答案:

答案 0 :(得分:10)

具有初始值设定项的文件范围内的对象标识符的外部声明是定义。声明int x = 0;是一个定义,因为x已初始化。

在文件范围内没有初始值设定项的对象标识符的外部声明是暂定定义。声明struct {…} x;是一个暂定的定义,因为x未初始化。

链接时的多个定义会导致错误。

链接时的多个暂定定义合并为单个定义,初始化为零。

如果您将int x = 0;更改为int x;,则不会出现链接错误。如果您将struct {…} x;更改为struct {…} x = {0};,则会收到链接错误。

答案 1 :(得分:9)

下面的代码

struct
{
    int a;
    int b;
} x;

声明类型x的变量struct,没有标记。对于计划在单个编译单元中使用的静态结构,这是可以的,但如果您计划在多个.c文件中共享struct,则不应该这样做。相反,您应该为struct定义一个标记,或为其创建一个typedef,并使用srtruct my_struct语法分别声明该类型的变量。

以下是一个例子:

将此struct声明放在标题中:

struct a_and_b
{
    int a;
    int b;
};

将此变量声明放在.c文件中:

static struct a_and_b x;

现在x不再是全局的:您可以在.c文件中访问它,但从外部看不到它。如果要使其全局化,但避免链接器错误,请添加

extern struct a_and_b x;

到标题,并从.c文件中的声明中删除static