模板:
类型或模板不能用于__global__函数模板实例的类型,非类型或模板模板参数或__device __
/ __ constant__
变量实例,如果:
- 类型或模板在
__host__
或__host__
__device__
中定义。 - 类型或模板是具有私有或受保护访问权限的类成员,其父类未在
__device__
或__global__
函数中定义。 - 类型未命名
- 该类型由上述任何类型组合而成。
例子:
template <typename T>
__global__ void myKernel(void) { }
class myClass {
private:
struct inner_t { };
public:
static void launch(void)
{
// error: inner_t is used in template argument
// but it is private
myKernel<inner_t> << <1, 1 >> >();
}
};
// C++14 only
template <typename T> __device__ T d1;
template <typename T1, typename T2> __device__ T1 d2;
void fn() {
struct S1_t { };
// error (C++14 only): S1_t is local to the function fn
d1<S1_t> = {};
auto lam1 = [] {};
// error (C++14 only): a closure type cannot be used for
// instantiating a variable template
d2<int, decltype(lam1)> = 10;
}
Trigraphs and Digraphs:
Trigraph在任何平台上都不受支持。 Windows上不支持Digraphs
常量限定变量:
假设'V'表示一个名称空间范围变量或一个具有const限定类型并且没有执行空间注释的类静态成员变量(例如__device__
,__constant__
,__shared__
)。 V被认为是主机代码变量。
V的值可以直接在设备代码中使用,如果:
- V在使用点之前已经用一个常量表达式初始化,
- V的类型不是挥发性限定的,
-
它有以下几种类型之一:
- 内建浮点类型,除非使用Microsoft编译器作为主编译器时,
- 内置整型。
器件源代码不能包含对V的引用或取V的地址。
例子:
const int xxx = 10;
struct S1_t { static const int yyy = 20; };
extern const int zzz;
const float www = 5.0;
__device__ void foo(void) {
int local1[xxx]; // OK
int local2[S1_t::yyy]; // OK
int val1 = xxx; // OK
int val2 = S1_t::yyy; // OK
int val3 = zzz; // error: zzz not initialized with constant
// expression at the point of use.
const int &val3 = xxx; // error: reference to host variable
const int *val4 = &xxx; // error: address of host variable
const float val5 = www; // OK except when the Microsoft compiler is used as
// the host compiler.
}
const int zzz = 20;
弃用注释:
当使用gcc,clang,xlC,icc或pgcc主机编译器时,nvcc支持使用不推荐使用的属性,并且在使用cl.exe主机编译器时使用不推荐的declspec。 当C ++ 14方言被启用时,它也支持[[deprecated]]标准属性。 定义__CUDA_ARCH__
时(即在设备编译阶段),CUDA前端编译器将生成一个对__device__
,__global__
或__host__
__device__
函数体内对已弃用实体的引用的弃用诊断。 其他对已弃用实体的引用将由主机编译器处理,例如,来自__host__
函数的引用。
CUDA前端编译器不支持各种主机编译器支持的#pragma gcc诊断或#pragma警告机制。 因此,CUDA前端编译器生成的弃用诊断不受这些编译指示的影响,但主机编译器生成的诊断将受到影响。 可以使用nvcc标志-Wno-deprecated-声明来取消所有的弃用警告,并且可以使用flag -Werror = deprecated-声明将弃用警告转化为错误。