C标题重复符号问题

时间:2014-12-02 19:48:51

标签: c++ c cuda header-files duplicate-symbol

这是我第一次处理一个比简单的write-single-source-file-and-compile例程稍微复杂一点的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 ***/
const double OMEGA_0 = 6.447421494058077e+09;

/* other constants defined in the middle */

#endif

multigpu.cu

#include "env_vars.h"
/* assigns h_n_osc */

adm_matrix.cu

#include "env_vars.h"
/* uses h_n_osc */

在Nsight Eclipse Edition中构建项目会导致链接器抱怨h_n_osc变量被定义两次:

duplicate symbol _h_n_osc in:
    ./adm_matrix.o
    ./multigpu.o
ld: 1 duplicate symbol for architecture x86_64

通过互联网搜索,我意识到将h_n_osc变量的声明移至multigpu.cu并在extern中将其重新声明为adm_matrix.cu变量(以及我以后可能需要它的地方)解决问题,实际上它确实

问题解决了,但我想深入研究一下:

  1. 为什么链接器也不抱怨d_n_osc变量?为什么常量(例如OMEGA_0)同样不是问题?
  2. 这是否意味着无法将全局变量放在头文件中?
  3. 最让我感到困惑的是,互联网上的许多消息来源指出,只有当头文件包含变量的定义时才会发生重复的符号错误,而其简单的声明< / em>不应该构成问题。我很难相信这一点的原因是即使我的标题只包含一个声明,我也面临着这个问题!我错过了什么吗?
  4. 提前感谢您的耐心,伙计们!

1 个答案:

答案 0 :(得分:9)

头文件通常应包含声明性代码。 h_n_osc应该声明,而不是已定义

extern unsigned int h_n_osc;

在您的至少一个模块中,或者您自己的新模块中,您将需要一个定义;例如:

<强> env_vars.cu

#include "env_vars.h"
unsigned int h_n_osc;

然后链接那个。或者,您当然可以将定义放在其中一个现有模块multigpu.cu或adm_matrix.cu中。

我不确定CUDA __device__扩展名的语义,虽然它可能链接,但它不一定正确;您最终可能会引用每个模块引用设备变量的单独副本;可能有必要使用extern来限定它。 This question似乎可以解决这个问题。