重新声明 C 中的共享全局 typedef'd 变量



我遇到了一个问题,我似乎无法解决该问题,其中声称将全局变量重新播出在声明的唯一行中。我有以下代码:

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不会构成任何问题;TST只有变量,即在test_regs.h中声明的类型,才会产生上述错误。这意味着错误不能是由于标题tasks.h多次声明。有人知道为什么我的代码显然是非法的吗?

我会注意到,如果除了test_regs.h以外,我摆脱了所有标题,并在一个统一的C文件中进行声明,问题就会消失。另外,我确实必须将test_regs.h标头与tasks.h标头分开,test_regs.h是机器生成的,而tasks.h则没有,并且会根据用法而更改。


好吧,由于这显然没有让主持人的人沉没,所以这不是一个重复的问题。我可以构建我的代码,以便满足现有帖子中的建议,如下所示(甚至吸入标头,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有一些特定的东西正在打破全局共享;这不仅是一般的"我如何共享全局变量"问题。

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

全局变量应为在一个.c文件中定义。任何需要引用它的.c文件都应包括该全局具有声明的标头文件。声明说"这个变量存在于某个地方",但没有确切说明。

在任务中。

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

然后您在任务中定义它们。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关键字,而函数声明则不。

相关内容

  • 没有找到相关文章

最新更新