Error: redefinition of "a static variable" in C header files
Error: redefinition of "a static variable" in C header files
我在两个不同的文件中声明了一些静态变量(比如 var1 和 var2)。变量在两个文件中具有相同的名称。一些变量(比如 var1)没有在它们的声明中初始化,有些是(var2),如下所示。
file1.h
static bool var1;
static bool var2 = false;
file2.h
static bool var1;
static bool var2 = false;
据我了解,静态变量仅限于声明它们的 c 文件(或 h 文件),因此在多个头文件中使用相同的变量名应该是安全的。但是当我编译代码时,我得到错误 "redefinition of var2",仅针对已初始化的变量。
- 为什么这个错误只发生在 var2 上?
- 我的实现没问题吗?
编辑:
由于有人提到要使用 extern 关键字,我想澄清一下,var1 和 var2 在不同的 c 文件中应该有不同的值,并且应该只限于它们各自的文件,
没有。 var1
的多重声明是可以的,但是var2
的多重定义就不行了。您不能对变量进行两次初始化...即使值相同。
我使用预处理器守卫解决此类问题,例如:
#if !defined(MY_APP__VARS_DEFINED)
static int var1, var2=0;
#define MY_APP__VARS_DEFINED
#endif
即便如此,我也不建议在多个 header 文件中复制定义。这是一个维护问题。迟早,有人可能会更改一个 header 中的初始值,而不会找到它定义的所有其他 header。这也会使重命名 ("refactoring") 变得更加困难。 (...并且违反了 DRY Principle。)
不过,您可能需要重新考虑您的设计。全局变量通常会导致脆弱的应用程序;更难维护,更容易损坏。
为什么这个错误只发生在 var2 上? 如果你在同一个源文件 test.cpp
中包含 file1.h
和 file2.h
那么 var2
将有两个定义,编译器无法选择采用哪一个并抛出错误。
为了避免这种情况,在头文件 .h
中将 var2
声明为 extern
并在相应的源 .cpp
文件中进行定义。
虽然在 var1
的情况下它只是 declaration
而不是 definition
所以它不会抛出错误,即可以进行多重声明。
还有 static
声明,如
static bool var1;
表示变量var1
仅在当前编译单元可见。
旁注,static
变量具有内部链接,即它隐藏了来自其他翻译单元的 static
变量。尽管 static
个变量可以在多个翻译单元中 defined
。
和extern
变量具有外部链接,即extern
变量将对其他翻译单元可见,但extern
变量应该只在一个翻译单元中定义。
如果源文件同时包含 file1.h 和 file2.h,它将有多个 var2
的定义。这就是导致错误的原因。
与其在头文件中声明/定义这些静态变量,不如将它们直接放入必要的 C 源文件中。这样您就不必处理多个定义。
我在两个不同的文件中声明了一些静态变量(比如 var1 和 var2)。变量在两个文件中具有相同的名称。一些变量(比如 var1)没有在它们的声明中初始化,有些是(var2),如下所示。
file1.h
static bool var1;
static bool var2 = false;
file2.h
static bool var1;
static bool var2 = false;
据我了解,静态变量仅限于声明它们的 c 文件(或 h 文件),因此在多个头文件中使用相同的变量名应该是安全的。但是当我编译代码时,我得到错误 "redefinition of var2",仅针对已初始化的变量。
- 为什么这个错误只发生在 var2 上?
- 我的实现没问题吗?
编辑: 由于有人提到要使用 extern 关键字,我想澄清一下,var1 和 var2 在不同的 c 文件中应该有不同的值,并且应该只限于它们各自的文件,
没有。 var1
的多重声明是可以的,但是var2
的多重定义就不行了。您不能对变量进行两次初始化...即使值相同。
我使用预处理器守卫解决此类问题,例如:
#if !defined(MY_APP__VARS_DEFINED)
static int var1, var2=0;
#define MY_APP__VARS_DEFINED
#endif
即便如此,我也不建议在多个 header 文件中复制定义。这是一个维护问题。迟早,有人可能会更改一个 header 中的初始值,而不会找到它定义的所有其他 header。这也会使重命名 ("refactoring") 变得更加困难。 (...并且违反了 DRY Principle。)
不过,您可能需要重新考虑您的设计。全局变量通常会导致脆弱的应用程序;更难维护,更容易损坏。
为什么这个错误只发生在 var2 上? 如果你在同一个源文件 test.cpp
中包含 file1.h
和 file2.h
那么 var2
将有两个定义,编译器无法选择采用哪一个并抛出错误。
为了避免这种情况,在头文件 .h
中将 var2
声明为 extern
并在相应的源 .cpp
文件中进行定义。
虽然在 var1
的情况下它只是 declaration
而不是 definition
所以它不会抛出错误,即可以进行多重声明。
还有 static
声明,如
static bool var1;
表示变量var1
仅在当前编译单元可见。
旁注,static
变量具有内部链接,即它隐藏了来自其他翻译单元的 static
变量。尽管 static
个变量可以在多个翻译单元中 defined
。
和extern
变量具有外部链接,即extern
变量将对其他翻译单元可见,但extern
变量应该只在一个翻译单元中定义。
如果源文件同时包含 file1.h 和 file2.h,它将有多个 var2
的定义。这就是导致错误的原因。
与其在头文件中声明/定义这些静态变量,不如将它们直接放入必要的 C 源文件中。这样您就不必处理多个定义。