C中的共享全局类型定义变量已重新声明

时间:2016-12-28 01:48:38

标签: c variables gcc global-variables typedef

我遇到了一个我似乎无法解决的问题,即声称全局变量在声明它的唯一行上被重新声明。我有以下代码:

test_regs.h:

#define    TEST_REGS_BASE_ADDRESS       0xA0080000

typedef struct {
    union {
        unsigned int data;
        struct {
            unsigned int RESERVED     : 16;
            unsigned int CHAR1        : 8;
            unsigned int CHAR0        : 8;
        };
    };
} TEST_REG_STRUCT;

typedef struct {
    TEST_REG_STRUCT                     TEST_REG;
} *TEST_REGS;

tasks.h:

#ifndef TASKS_H
#include "test_regs.h"

volatile TEST_REGS              TST; // This line throws an error
volatile int                    ok_global;

void func();

#define TASKS_H
#endif

tasks.c:

#include "tasks.h"

void func() {
    TST->TEST_REG.CHAR1 = 0x52;
    TST->TEST_REG.CHAR0 = 0x51;
    ok_global++;
}

main.c中:

#include "tasks.h"

main() {
    TST = (TEST_REGS) TEST_REGS_BASE_ADDRESS;
    ok_global = 0;
    func();
}

我尝试使用以下命令编译上述代码(使用为Leon3处理器开发的最小版GCC):

sparc-elf-gcc -msoft-float -c -g -O2 -o test.o tasks.c main.c

该编译尝试产生以下错误:

tasks.h:4: error: conflicting types for 'TST'

tasks.h:4: error: previous declaration of 'TST' was here

值得注意的是,全局变量ok_global不会造成任何问题;只有变量,已在test_regs.h中声明的类型,TST会产生上述错误。这意味着错误不能归因于标头tasks.h以某种方式多次声明。有没有人知道为什么我写的代码显然是非法的?

我注意到,如果我除掉test_regs.h之外的所有标题,并在一个统一的C文件中声明,问题就会消失。另外,我必须将test_regs.h标头与tasks.h标头分开,test_regs.h是机器生成的,tasks.h不是,并且会根据使用情况而改变。< / p>

好吧,因为对于有主持人的人来说,这显然不会下沉,这不是一个重复的问题。我可以构建我的代码以满足现有帖子中的建议,如下所示(甚至吮吸标题,test_regs.h):

tasks.h:

#ifndef TASKS_H
#define TASKS_H
#define    TEST_REGS_BASE_ADDRESS       0xA0080000

typedef struct {
    union {
        unsigned int data;
        struct {
            unsigned int RESERVED     : 16;
            unsigned int CHAR1        : 8;
            unsigned int CHAR0        : 8;
        };
    };
} TEST_REG_STRUCT;

typedef struct {
    TEST_REG_STRUCT                     TEST_REG;
} *TEST_REGS;

extern volatile TEST_REGS              TST;
volatile int                    ok_global;

void func();

#endif

tasks.c:

#include "tasks.h"

volatile TEST_REGS TST;

void func() {
    TST->TEST_REG.CHAR1 = 0x52;
    TST->TEST_REG.CHAR0 = 0x51;
    ok_global++;
}

main.c中:

#include "tasks.h"

main() {
    TST = (TEST_REGS) TEST_REGS_BASE_ADDRESS;
    ok_global = 0;
    func();
}

编译命令:

sparc-elf-gcc -msoft-float -c -g -O2 -o test.o tasks.c main.c

结果:

tasks.h:20: error: conflicting types for 'TST'

tasks.c:3: error: previous declaration of 'TST' was here

TST特有的东西打破了全球共享;这不仅仅是一个“我如何分享全局变量”的问题。

1 个答案:

答案 0 :(得分:3)

tasks.h中的变量TSTok_global 已定义。由于main.c和tasks.c都包含此标头,因此这两个模块中都定义了这些变量。当这些模块然后链接在一起时,您会得到多个定义的错误。

全局变量应该只在一个.c文件中定义。任何需要引用它的.c文件都应该包含一个头文件,该文件具有此全局的声明。声明说&#34;这个变量存在于某个地方&#34;但并不确切地说明在哪里。

在tasks.h中,您声明如下变量:

extern volatile TEST_REGS              TST;
extern volatile int                    ok_global;
void func();

然后在tasks.c中定义它们:

#include "tasks.h"

volatile TEST_REGS              TST;
volatile int                    ok_global;

void func() {
    TST->TEST_REG.CHAR1 = 0x52;
    TST->TEST_REG.CHAR0 = 0x51;
    ok_global++;
}

请注意,您已使用func功能执行此操作。不同之处在于变量声明需要extern关键字,而函数声明则不需要。