extern int global_variable; /* Declaration of the variable */
file1. c
#include "file3.h" /* Declaration made available here */#include "prog1.h" /* Function declarations */
/* Variable defined here */int global_variable = 37; /* Definition checked against declaration */
int increment(void) { return global_variable++; }
#define DEFINE_VARIABLES#include "file3a.h" /* Variable defined - but not initialized */#include "prog3.h"
int increment(void) { return global_variable++; }
/*** This header must not contain header guards (like <assert.h> must not).** Each time it is invoked, it redefines the macros EXTERN, INITIALIZE** based on whether macro DEFINE_VARIABLES is currently defined.*/#undef EXTERN#undef INITIALIZE
#ifdef DEFINE_VARIABLES#define EXTERN /* nothing */#define INITIALIZE(...) = __VA_ARGS__#else#define EXTERN extern#define INITIALIZE(...) /* nothing */#endif /* DEFINE_VARIABLES */
文件1c. h
#ifndef FILE1C_H_INCLUDED#define FILE1C_H_INCLUDED
struct oddball{int a;int b;};
extern void use_them(void);extern int increment(void);extern int oddball_value(void);
#endif /* FILE1C_H_INCLUDED */
文件2c. h
/* Standard prologue */#if defined(DEFINE_VARIABLES) && !defined(FILE2C_H_DEFINITIONS)#undef FILE2C_H_INCLUDED#endif
#ifndef FILE2C_H_INCLUDED#define FILE2C_H_INCLUDED
#include "external.h" /* Support macros EXTERN, INITIALIZE */#include "file1c.h" /* Type definition for struct oddball */
#if !defined(DEFINE_VARIABLES) || !defined(FILE2C_H_DEFINITIONS)
/* Global variable declarations / definitions */EXTERN int global_variable INITIALIZE(37);EXTERN struct oddball oddball_struct INITIALIZE({ 41, 43 });
#endif /* !DEFINE_VARIABLES || !FILE2C_H_DEFINITIONS */
/* Standard epilogue */#ifdef DEFINE_VARIABLES#define FILE2C_H_DEFINITIONS#endif /* DEFINE_VARIABLES */
#endif /* FILE2C_H_INCLUDED */
文件3c. c
#define DEFINE_VARIABLES#include "file2c.h" /* Variables now defined and initialized */
int increment(void) { return global_variable++; }int oddball_value(void) { return oddball_struct.a + oddball_struct.b; }
/*** This header must not contain header guards (like <assert.h> must not).** Each time it is included, the macro HEADER_DEFINING_VARIABLES should** be defined with the name (in quotes - or possibly angle brackets) of** the header to be included that defines variables when the macro** DEFINE_VARIABLES is defined. See also: external.h (which uses** DEFINE_VARIABLES and defines macros EXTERN and INITIALIZE** appropriately).**** #define HEADER_DEFINING_VARIABLES "file2c.h"** #include "externdef.h"*/
#if defined(HEADER_DEFINING_VARIABLES)#define DEFINE_VARIABLES#include HEADER_DEFINING_VARIABLES#undef DEFINE_VARIABLES#undef HEADER_DEFINING_VARIABLES#endif /* HEADER_DEFINING_VARIABLES */
#include <stdio.h>
int not_extern_int = 1;extern int extern_int;
void main() {printf("%d\n", not_extern_int);printf("%d\n", extern_int);}
编译和反编译:
gcc -c main.creadelf -s main.o
输出包含:
Num: Value Size Type Bind Vis Ndx Name9: 0000000000000000 4 OBJECT GLOBAL DEFAULT 3 not_extern_int12: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND extern_int
#ifdef MAIN_C#define GLOBAL/* #warning COMPILING MAIN.C */#else#define GLOBAL extern#endifGLOBAL unsigned char testing_mode; // example var used in several C files