C++ 带有C头的重复符号问题
这是我第一次处理CUDA项目,它比简单的编写单个源文件和编译例程稍微复杂一些。正如所料,我在使用C头时遇到了一些问题,即重复符号 根据链接器,在多个C++ 带有C头的重复符号问题,c++,c,cuda,header-files,duplicate-symbol,C++,C,Cuda,Header Files,Duplicate Symbol,这是我第一次处理CUDA项目,它比简单的编写单个源文件和编译例程稍微复杂一些。正如所料,我在使用C头时遇到了一些问题,即重复符号 根据链接器,在多个.cu文件中包含以下头文件会产生冲突: env_vars.h #ifndef ENV_VARS_H_ #define ENV_VARS_H_ /*** GLOBAL VARIABLES ***/ unsigned int h_n_osc; __device__ unsigned int d_n_osc; /*** CONSTANTS ***/ c
.cu
文件中包含以下头文件会产生冲突:
env_vars.h
#ifndef ENV_VARS_H_
#define ENV_VARS_H_
/*** GLOBAL VARIABLES ***/
unsigned int h_n_osc;
__device__ unsigned int d_n_osc;
/*** CONSTANTS ***/
const double OMEGA_0 = 6.447421494058077e+09;
/* other constants defined in the middle */
#endif
multigpu.cu
#include "env_vars.h"
/* assigns h_n_osc */
#include "env_vars.h"
/* uses h_n_osc */
#include "env_vars.h"
unsigned int h_n_osc;
adm_matrix.cu
#include "env_vars.h"
/* assigns h_n_osc */
#include "env_vars.h"
/* uses h_n_osc */
#include "env_vars.h"
unsigned int h_n_osc;
在Nsight Eclipse版本中构建项目会导致链接器抱怨h\u n\u osc
变量被定义了两次:
duplicate symbol _h_n_osc in:
./adm_matrix.o
./multigpu.o
ld: 1 duplicate symbol for architecture x86_64
通过互联网搜索,我意识到将h\u n\u osc
变量的声明移动到multigpu.cu
,并在adm\u matrix.cu
中重新声明为extern
变量(以及以后可能需要它的任何地方)可以解决问题,事实上它确实解决了这个问题
问题已解决,但我想对此进行更深入的研究:
d\n\u osc
变量?为什么常数(比如ω0)同样不是问题各位,提前感谢你们的耐心等待 头文件通常只应包含声明性代码
h_n_osc
应在此处声明,而不是定义
在至少一个模块中,或者在一个新模块中,您需要一个定义;例如:
环境变量cu
#include "env_vars.h"
/* assigns h_n_osc */
#include "env_vars.h"
/* uses h_n_osc */
#include "env_vars.h"
unsigned int h_n_osc;
然后把它链接起来。当然,您也可以将定义放在现有模块multigpu.cu或adm_matrix.cu中
我不确定扩展的语义,虽然它可能链接,但不一定正确;最终,每个模块可能引用设备变量的单独副本;可能还需要使用
extern
对其进行限定。似乎解决了这个问题。信不信由你,未签名的int h_n_osc
是一个定义。请在单个.c文件中定义变量,然后头文件需要对这些变量使用“extern”语句冲击揭露,@aschepler!事实证明,我一直误解了变量的声明和定义之间的区别。非常感谢。正确,\uuuuuuu设备\uuuuuu
(和\uuuuu常量\uuuuuuuuu
)变量。@RobertCrovella:谢谢;因此,它们的语义与静态
和常量
相似,这似乎是一个问题。但我会说是的,类似的。在没有其他细节的情况下,CUDA应该与C++编译器的行为类似。代码> >“Deice”/“代码>和<代码>·y-康斯坦特变量在普通的主机C++代码中是不可引用的,但这是一个单独的主题。谢谢你们,伙计们!正如我在上面所评论的,我的大多数怀疑显然源于我对声明和变量定义的概念的误解。为了完整性,这里的栈溢出也回答了我原来的帖子中的问题2:<代码> const <代码>蚂蚁在C++中有默认的内部链接(而它们默认为C中的外部链接),所以我的解决方案(即在头中定义它们)很好,因为CUDA C实际上是CUDA C/C++;纯C编译器也会拒绝这些常数。@ TeQueCurrad:如果你声明const的代码>静态const < /> >,那么C和C++中的语义是相同的。但是,如果代码占用了const的地址,那么它们在每个模块中都是不同的,但是在C++中,至少如果不使用const的地址,所有引用都会被文字替换。