Я впервые занимаюсь проектом 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
(и там, где мне это может понадобиться позже) решает проблему, что на самом деле делает.
Проблема решена, но я хотел бы разобраться в этом подробнее:
- Почему компоновщик также не жалуется на переменную
d_n_osc
? И почему константы (например,OMEGA_0
) тоже не проблема? - Означает ли это, что нельзя размещать глобальные переменные в файлах заголовков?
- Что меня больше всего озадачивает, так это то, что ряд источников в Интернете заявляют, что ошибки дублирования символов должны происходить только тогда, когда файл заголовка содержит определение переменной, а его простое объявление не должно быть проблемой. Причина, по которой мне трудно в это поверить, заключается в том, что я столкнулся с проблемой, хотя мой заголовок содержит только объявление! Я что-то упускаю?
Заранее благодарим за терпение, ребята!
unsigned int h_n_osc;
- это определение. - person aschepler   schedule 02.12.2014