这个问题是this one的后续问题
它是关于nvcc
编译器在设备代码中将static constexpr
类变量识别为未定义的,如果变量是odr-used的话。但是,我找不到理由,为什么它不起作用。
错误消息是:
error: identifier "Tester<int> ::ONE" is undefined in device code
用
编译nvcc -std=c++11 -ccbin=/usr/bin/g++-4.9 -arch=sm_30 main.cu
nvcc
编译器版本为release 8.0, V8.0.26
#include <iostream>
#include <cstdlib>
#ifdef __CUDACC__
#define HD __host__ __device__
#else
#define HD
#endif
HD void doSomething(const int& var ) {};
template<typename T> class Tester
{
public:
static constexpr int ONE = 1;
HD void test()
{
doSomething( ONE );
}
};
template<typename T> constexpr int Tester<T>::ONE;
int main()
{
using t = int;
Tester<t> tester;
tester.test();
return EXIT_SUCCESS;
}
问题是不关于修复这个特定的代码(这可以通过传递var而不是const引用来完成 - 至少编译器不再抱怨,尽管它是一个odr-使用,不是吗?)
问题是,这是否是nvcc
编译器的错误或是否有一些正当理由,为什么这不起作用(我在NVIDIA页面上没有找到任何暗示......)。
答案 0 :(得分:4)
我认为来自CUDA文档的E.2.13. Const-qualified variables部分的摘录解释了:
让V&#39; V&#39;表示命名空间范围变量或具有const限定类型且没有执行空间注释的类静态成员变量(例如,__ device__,__ conststant __,__ shared__)。 V被认为是主机代码变量。
如果出现以下情况,V的值可直接用于设备代码:
- V在使用点之前已使用常量表达式初始化,
- 它具有以下类型之一:
- 内置浮点类型,除非将Microsoft编译器用作主机编译器,
- 内置整体式。
设备源代码不能包含对V的引用或取V的地址。
我认为您的代码违反了最后一句 - 您的代码包含引用。