C++ .h文件中的全局常量将问题与gcc链接,可与g++;

C++ .h文件中的全局常量将问题与gcc链接,可与g++;,c++,c,gcc,C++,C,Gcc,我有两个.c文件和一个.h文件。在.h文件中,我声明了全局常量。当使用gcc构建时,我会遇到链接问题,告诉我常量定义了两次,尽管我已经定义了两次 #ifndef __FOO #define __FOO const struct foo bar = ... #endif 我明白了 然而,用g++编译完全相同的代码是完美的。C和C++处理H文件中声明的全局常量有什么不同吗?我应该考虑什么样的方法? 请注意,所有对象都需要共享常量的内存,因为我的资源有限。您应该只声明: const struct

我有两个.c文件和一个.h文件。在.h文件中,我声明了全局常量。当使用gcc构建时,我会遇到链接问题,告诉我常量定义了两次,尽管我已经定义了两次

#ifndef __FOO
#define __FOO

const struct foo bar = ...

#endif
我明白了

然而,用g++编译完全相同的代码是完美的。C和C++处理H文件中声明的全局常量有什么不同吗?我应该考虑什么样的方法?


请注意,所有对象都需要共享常量的内存,因为我的资源有限。

您应该只声明:

const struct foo bar;

并在
.c
文件中为其赋值。

您只应声明:

const struct foo bar;

并在
.c
文件中为其赋值。

您应该在
.h
文件中声明该常数,并在单个
.c
文件中定义它:

B.h:

extern const struct foo bar;
B.c:

#include "bar.h"

/* do this in a single file */
const struct foo bar = ...;
然后将
bar.h
包含在您想要访问的任何地方
bar

c:

#include "bar.h"

void doSomethingWithBar() {
    struct *foo something = &bar;
    ...
}
编辑(由Shahbaz编写):之所以这样做有效而代码不起作用,是因为当您包含一个文件时,该文件的内容是复制粘贴的,而不是#include(这与文件无关,您可以包含任何内容,包括扩展名为.h的文件只是一种约定)。所以当你说
const-struct-foo-bar
在头文件中,并将其包含在两个文件中,这与在两个文件中写入该行完全相同,因此在两个文件中定义变量,从而定义链接错误

您的标题保护也不起作用(标题)


)因为您的每个源文件都是单独编译的,因此当bar.h包含在一个文件中并且定义了
\uuu bar\u h\uuuu
时,在编译下一个文件时,
\uu bar\u h\uuuu
的定义将丢失。

您应该在
.h
文件中声明常量,并在单个
.c
文件中定义它:

B.h:

extern const struct foo bar;
B.c:

#include "bar.h"

/* do this in a single file */
const struct foo bar = ...;
然后将
bar.h
包含在您想要访问的任何地方
bar

c:

#include "bar.h"

void doSomethingWithBar() {
    struct *foo something = &bar;
    ...
}
编辑(由Shahbaz编写):之所以这样做有效而代码不起作用,是因为当您包含一个文件时,该文件的内容是复制粘贴的,而不是#include(这与文件无关,您可以包含任何内容,包括扩展名为.h的文件只是一种约定)。所以当你说
const-struct-foo-bar
在头文件中,并将其包含在两个文件中,这与在两个文件中写入该行完全相同,因此在两个文件中定义变量,从而定义链接错误

您的标题保护也不起作用(标题)


)因为您的每个源文件都是单独编译的,因此当一个文件中包含bar.h并定义了
\uuuu bar\u h\uuu
时,下一个文件编译时,
\uu bar\u h\uu
的定义将丢失。

完美!这很有效。为什么要使用
extern
?正如@Clement.GCC所建议的那样,它似乎也可以在没有的情况下工作,神奇地找到多个实例并将它们放在一起。但是,如果使用其他编译器,如
tcc
,则可能会出现错误。
extern
声明变量而不定义它。它告诉编译器这个定义存在于另一个文件中。太好了!这很有效。为什么要使用
extern
?正如@Clement.GCC所建议的那样,它似乎也可以在没有的情况下工作,神奇地找到多个实例并将它们放在一起。但是,如果使用其他编译器,如
tcc
,则可能会出现错误。
extern
声明变量而不定义它。它告诉编译器这个定义存在于另一个文件中。这很好,谢谢!正如@arnaud所建议的,您可以使用
extern const…
。“你知道哪一个是可取的吗?”约翰我和阿诺的建议一样。如果你用你的代码构建了一个库,它就会“按原样”工作。这很好,谢谢!正如@arnaud所建议的,您可以使用
extern const…
。“你知道哪一个是可取的吗?”约翰我和阿诺的建议一样。如果您用代码构建一个库,那么它将“按原样”工作。