I've encountered a problem that I cannot seem to resolve in which a global variable is claimed to be redeclared on the only line where it is declared. I have the following code:
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();
}
I attempt to compile the above code with the following command (using a minimal version of GCC developed for the Leon3 processor):
sparc-elf-gcc -msoft-float -c -g -O2 -o test.o tasks.c main.c
That compile attempt produces the following errors:
tasks.h:4: error: conflicting types for 'TST'
tasks.h:4: error: previous declaration of 'TST' was here
Notably, the global variable, ok_global
does not pose any problem; only the variable, the type having been declared in test_regs.h
, TST
produces the above error. This means that the error cannot be due to the header tasks.h
somehow getting declared multiple times. Does anyone have any idea why my code as written is apparently illegal?
I'd note that, if I get rid of all headers, except for test_regs.h
, and make the declaration in one unified C
file, the problem goes away. Also, I really must have the test_regs.h
header separated from the tasks.h
header, test_regs.h
is machine-generated while tasks.h
is not, and will change depending on the usage.
Okay, since this apparently isn't sinking in for moderator-minded folks, this is not a duplicate question. I can structure my code in order to meet the suggestions in the existing post as follows (even sucking in the header, 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();
}
Compile command:
sparc-elf-gcc -msoft-float -c -g -O2 -o test.o tasks.c main.c
Result:
tasks.h:20: error: conflicting types for 'TST'
tasks.c:3: error: previous declaration of 'TST' was here
There is something specific to TST
that is breaking global sharing; this is not just a general "how do I share global variables" question.