nvcc编译器将静态constexpr识别为设备代码中的未定义

时间:2016-09-29 13:20:38

标签: c++ cuda constexpr nvcc

这个问题是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

给出了一个最小的例子(前一个问题中关于MWE的缩短版本,专注于这一特定问题)
#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页面上没有找到任何暗示......)。

1 个答案:

答案 0 :(得分:4)

我认为来自CUDA文档的E.2.13. Const-qualified variables部分的摘录解释了:

让V&#39; V&#39;表示命名空间范围变量或具有const限定类型且没有执行空间注释的类静态成员变量(例如,__ device__,__ conststant __,__ shared__)。 V被认为是主机代码变量。

如果出现以下情况,V的值可直接用于设备代码:
        
  • V在使用点之前已使用常量表达式初始化,
  •     
  • 它具有以下类型之一:     
              
    • 内置浮点类型,除非将Microsoft编译器用作主机编译器,
    • 内置整体式。

设备源代码不能包含对V的引用或取V的地址。

我认为您的代码违反了最后一句 - 您的代码包含引用。