【问题标题】:CUDA 8.0: Compile Error with Template Friend in NamespaceCUDA 8.0:在命名空间中使用模板友元编译错误
【发布时间】:2018-04-12 07:32:06
【问题描述】:

我注意到以下代码可以使用 g++/clang++-3.8 编译,但不能使用 nvcc:

#include <tuple>   // not used, just to make sure that we have c++11
#include <stdio.h>

namespace a {
template<class T>
class X {
  friend T;
};
}

我得到以下编译错误:

/usr/local/cuda-8.0/bin/nvcc -std=c++11 minimum_cuda_test.cu
nvcc warning : The 'compute_20', 'sm_20', and 'sm_21' architectures are deprecated, and may be removed in a future release (Use -Wno-deprecated-gpu-targets to suppress warning).
minimum_cuda_test.cu:7:10: error: ‘T’ in namespace ‘::’ does not name a type
   friend T;

有趣的是,这适用于 nvcc:

#include <tuple>   // not used, just to make sure that we have c++11
#include <stdio.h>

template<class T>
class X {
  friend T;
};

这是编译器中的错误吗?我认为 nvcc 会在内部使用 g++ 或 clang 作为编译器,所以我很困惑为什么这适用于我的本地编译器但不适用于 nvcc。

【问题讨论】:

    标签: c++11 templates compiler-errors cuda nvcc


    【解决方案1】:

    在这两种情况下,代码都是由 g++ 编译的。但是,当您将 .cu 文件传递​​给 nvcc 时,它会将代码通过 CUDA C++ 前端,然后再将其传递给主机编译器。查看 CUDA 8 和 gcc 4.8,我看到代码已经从

    namespace a {
    template<class T>
    class X {
      friend T;
    };
    }
    

    namespace a {
    template< class T>
    class X {
    friend ::T;
    };
    

    您可以看到前端已将模板化的朋友替换为等效的,但带有一个前置匿名命名空间,这破坏了编译。我不是 C++ 语言律师,但在我看来,这似乎是 CUDA 前端的一个错误。我建议向 NVIDIA 报告。

    【讨论】:

    • 我明白了,这就解释了。附带说明:如何查看 CUDA C++ 前端的输出?
    • @MatthiasSpringer:您可以将-v --keep 传递给 nvcc,这将向您显示在编译过程中发生错误的位置以及正在处理哪个输入文件,然后您自己检查该输入文件。
    猜你喜欢
    • 2018-10-20
    • 1970-01-01
    • 1970-01-01
    • 2011-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-24
    • 2017-12-16
    相关资源
    最近更新 更多