CUDA 8.0:在命名空间中使用模板朋友编译错误

时间:2017-10-31 07:43:43

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

我注意到以下代码用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。

1 个答案:

答案 0 :(得分:2)

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

转换而来
namespace a {
template<class T>
class X {
  friend T;
};
}

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

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