你在标题中使用了包含守卫吗?通常,您希望将头部结构如下:
#ifndef _HEADER_FILE_H
#define _HEADER_FILE_H
// actual definitions
#endif
Run Code Online (Sandbox Code Playgroud)
还有#pragma once,但这不是标准.
不要在头文件中声明它(虽然从技术上讲,我的意思是不在那里定义它).
在您的头文件中,您应该:
extern int variableIWantOneCopyOfOnly;
Run Code Online (Sandbox Code Playgroud)
然后,在要链接的单个C源文件中,放入:
int variableIWantOneCopyOfOnly;
Run Code Online (Sandbox Code Playgroud)
前者将让所有源文件知道变量的存在,但不为它分配空间.包含第二行的单个翻译单元将为其分配空间,链接器将修复对其的所有引用.
包含警卫对多个定义没有帮助,因为它们只停止包含在单个翻译单元中.
我的意思是,如果您有以下文件:
xyz.h: xyz1.c: xyz2.c:
#ifnef XYZ #include "xyz.h" #include "xyz.h"
#define XYZ
int a;
#endif
Run Code Online (Sandbox Code Playgroud)
并执行如下命令:
gcc xyz1.c xyz2.c
Run Code Online (Sandbox Code Playgroud)
然后他们都会得到自己的副本a,而不是共享副本,因为include guard的范围是翻译单元,而不是链接器创建的可执行文件.