3

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

这两个源文件包括标题。

这是标题的代码:

struct
{
    int a;
    int b
} x;

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

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

int x = 0;

最后一段代码对我来说很有意义,但我真的不明白带有结构的那个..

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

编辑编辑:
我回来了常规 C 中的示例。正如您所看到的,不仅可以使用结构,还可以使用常规变量。

源1.c

#include "header.h"

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

源代码2.c

#include "header.h"

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

头文件.h

#include <stdio.h>

int x;

输出

source2: 0
source2: 1

请注意,不能声明 x 以使其正常工作,否则它会像这里的每个人所说的那样给出链接器错误。(我不知道为什么它适用于嵌入式系统..)

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

4

2 回答 2

10

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

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

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

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

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

于 2012-09-28T17:16:12.873 回答
9

下面这段代码

struct
{
    int a;
    int b;
} x;

声明一个没有标签x的类型struct变量。这对于您计划在单个编译单元中使用的静态结构是可以的,但如果您计划struct在多个 .c 文件中共享 a ,则不应该这样做。相反,您应该为您定义一个标签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;

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

于 2012-09-28T16:49:06.213 回答