跨文件共享结构体的非常规实现方式技术咨询
Great question—let’s unpack this unconventional way of sharing a struct and global variable across files, and go over why it’s problematic, plus the standard approach you should use instead.
First, let’s clarify the intent: The author wants to share two things across multiple files:
- The
struct datatype definition, so all files understand the structure’s layout - A global instance
fooof that struct, so all files can access and modify the same variable
The problem lies in how they’re attempting to share the foo variable.
Your observed code defines the global variable foo directly in the header file (struct data foo;) without the extern keyword. Here’s why that’s a bad practice:
Linker Errors (Most Common Issue)
In C, a line likestruct data foo;at file scope counts as a tentative definition of a global variable. If multiple.cfiles include this header, each file will get its own definition offoo. When the linker tries to combine all object files, it’ll throw a multiple definition error (modern compilers like GCC with default settings catch this immediately).Older compilers might use a non-standard "common symbol" feature to merge these definitions, but this behavior is unreliable, non-portable, and can lead to hard-to-debug bugs.
Unpredictable Initialization and Behavior
Even if the linker somehow merges the definitions, the initialization order of global variables across files isn’t guaranteed. If one file initializesfoo.ato 5 and another expects that value, you might get garbage instead if the initialization runs in the wrong order. Worse, if the linker doesn’t merge them, you’ll end up with separate instances offooin different files—changes tofooin one file won’t affect the others, leading to silent, confusing bugs.Poor Maintainability
Putting a global variable directly in a header breaks encapsulation. Any file that includes the header can modifyfoodirectly, making it impossible to track where changes to the variable are happening. This becomes a nightmare to debug in larger codebases.
Here’s how you should implement cross-file shared variables correctly:
Step 1: Declare the Variable in the Header
Use the extern keyword to declare the variable in the header—this tells the compiler "this variable exists somewhere, but I’m not defining it here":
// file1.h #ifndef FILE1_H #define FILE1_H struct data { int a; }; // Declaration: informs other files about foo's existence extern struct data foo; void run(void); #endif
Step 2: Define the Variable in a Single .c File
Only define the variable once, in one source file—this is where the actual memory for foo is allocated:
// file1.c #include "file1.h" // Definition: allocates memory for foo (can initialize it here if needed) struct data foo; // Or with explicit initialization: struct data foo = {0}; void run() { // Your implementation here, e.g.: foo.a = 42; }
Step 3: Use It in Other Files
Any other .c file can include file1.h and use foo normally—since it’s declared with extern, the compiler knows to look for the definition in file1.c during linking:
// other_file.c #include "file1.h" void some_function() { // Access the single global foo instance printf("%d\n", foo.a); // Will print 42 after run() is called }
It usually comes down to one of two reasons:
- The developer doesn’t understand how
externworks, and incorrectly assumes defining the variable in the header will create a single shared instance. - The code was written for older compilers that allowed the non-standard "common symbol" merging, and hasn’t been updated to follow modern C standards.
内容的提问来源于stack exchange,提问作者ng.newbie

