c - C 中的共享全局 Typedef 变量重新声明

标签 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;

任务.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

任务.c:

#include "tasks.h"

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

主.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: 错误:“TST”类型冲突

tasks.h:4: 错误:'TST' 的先前声明在这里

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

我会注意到,如果我去掉所有 header (test_regs.h 除外),并在一个统一的 C 文件中进行声明,问题就来了离开。另外,我真的必须将 test_regs.h header 与 tasks.h header 分开,test_regs.h 是机器生成的,而 tasks.h 不是,并且会根据使用情况而改变。


好的,因为这显然不适合有主持人意识的人,所以这不是一个重复的问题。为了满足现有帖子中的建议,我可以构建我的代码,如下所示(甚至包含 header ,test_regs.h):

任务.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

任务.c:

#include "tasks.h"

volatile TEST_REGS TST;

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

主.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: 错误:“TST”类型冲突

tasks.c:3:错误:“TST”的先前声明在这里

有一些特定于 TST 的东西正在破坏全局共享;这不仅仅是一个一般性的“我如何共享全局变量”问题。

最佳答案

变量 TSTok_global 在 tasks.h 中定义。因为 main.c 和 tasks.c 都包含这个头文件,所以这些变量在两个模块中都定义了。当这些模块随后链接在一起时,您会收到多个定义的错误。

全局变量应该在同一个 .c 文件中定义。任何需要引用它的 .c 文件都应该包含一个头文件,该头文件具有此全局的声明。声明说“这个变量存在于某处”但没有说明确切位置。

在 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 关键字,而函数声明则不需要。

关于c - C 中的共享全局 Typedef 变量重新声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41354327/

相关文章:

c++ - 带有英特尔 C++ 编译器的 Armadillo 错误

c++ - 使内部类成为 C++ 中的 friend

gcc - x86_64 : Is it possible to "in-line substitute" PLT/GOT references?

c - OCaml 微基准测试

c++ - 传递给函数的数组参数不是常量指针吗?

php - 句点 ". "没有进入 URL 重写模式下 GET 请求中的 PHP 变量

随变量帮助一起发送的 php 引号

c - 微软 C 编译器 : Inline variable declaration?

c - 蛮力算法的优化还是替代?

c - malloc 函数在 C 程序中无法正常工作。程序崩溃