我想用 禁用特定的编译器警告nvcc
,特别是
警告:不允许 NULL 引用
我正在编写的代码使用NULL
引用是 SFINAE 的一部分,因此无法避免。
一个理想的解决方案是#pragma
在我们想要禁用警告的源文件中,但是如果存在一个编译器标志来只关闭有问题的警告,那么编译器标志也可以。
我想用 禁用特定的编译器警告nvcc
,特别是
警告:不允许 NULL 引用
我正在编写的代码使用NULL
引用是 SFINAE 的一部分,因此无法避免。
一个理想的解决方案是#pragma
在我们想要禁用警告的源文件中,但是如果存在一个编译器标志来只关闭有问题的警告,那么编译器标志也可以。
只是添加到关于 -xcudafe 的先前答案(还没有足够的声誉发表评论)
主要编辑:
cudaFE 显然是来自 Edison Design Group 的 Nvidia 定制版 C++ 前端。你可以在这里找到它的文档:http ://www.edg.com/docs/edg_cpp.pdf 。我目前指的是 2019 年 7 月 v5.1 手册中的页码。
@einpoklum 指出,像我最初在最初的帖子中所说的那样做 push/pop 是行不通的,特别是 #pragma push 会产生一个警告,表明它被忽略了。我无法复制警告,但实际上在下面的测试程序中,CUDA 10.1 和 CUDA 9.2 都没有推送/弹出实际上做任何事情(请注意,第 20 和 22 行不生成任何警告)。
但是,在本手册的第 75 页上,他们介绍了如何在没有推送/弹出的情况下进行本地化诊断严重性控制:
下面的例子抑制了 A 类声明中的“无意义的朋友声明”警告:
#pragma diag_suppress 522 class A { friend class A; }; #pragma diag_default 522 class B { friend class B; };
#pragma diag_default 将警告返回到默认状态。另一个例子是:
#pragma diag_suppress = code_is_unreachable
...
#pragma diag_default = code_is_unreachable
等号是可选的。测试表明这是可行的,并且真正本地化了严重性控制。此外,测试表明以这种方式添加诊断抑制会增加以前的诊断抑制 - 它不会取代。另外值得注意的是,在 CUDA 10.1 中,无法访问的代码在 CUDA 9.2 中没有生成警告。最后,手册的第 77 页提到了一种新的 push/pop 语法:
#pragma push_macro(“identifier”)
#pragma pop_macro(“identifier”)
但我无法让它在下面的程序中工作。
以上所有内容都在下面的程序中进行了测试,编译为nvcc -std=c++14 test_warning_suppression.cu -o test_warning_suppression
:
#include <cuda_runtime.h>
__host__ __device__ int return1(){
int j = -1; //warning given for both CUDA 9.2 and 10.1
return 1;
if(false){ return 0; } //warning given here for CUDA 9.2
}
#pragma push
#pragma diag_suppress = code_is_unreachable
#pragma diag_suppress = declared_but_not_referenced
__host__ __device__ int return2(){
int j = -1;
return 2;
if(false){ return 0; }
}
#pragma pop
__host__ __device__ int return3(){
int j = -1; //no warning given here
return 3;
if(false){ return 0; } //no warning here even in CUDA 9.2
}
//push/pop did not localize warning suppression, so reset to default
#pragma diag_default = declared_but_not_referenced
#pragma diag_default = code_is_unreachable
//warning suppression localized to lines above by diag_default!
__host__ __device__ int return4(){
int j = -1; //warning given for both CUDA 9.2 and 10.1
return 4;
if(false){ return 0; } //warning given here for CUDA 9.2
}
/* below does not work as of CUDA 10.1
#pragma push_macro(“identifier”)
#pragma diag_suppress = code_is_unreachable
__device__ int return5(){
return 5;
if(false){ return 0; }
}
#pragma pop_macro(“identifier”)
__device__ int return6(){
return 6;
if(false){ return 0; }
} */
int main(){ return 0; }
要增加 user2333829 的答案:如果您知道警告名称,您可以像这样禁用它:
-Xcudafe "--diag_suppress=boolean_controlling_expr_is_constant"
如果您不知道名称,请通过编译获取警告编号:
-Xcudafe --display_error_number
然后:
-Xcudafe --diag_suppress=<warning_number>
(注意:两个选项同时显然不起作用。)
您可以使用 w 标志来抑制警告
nvcc -w
我努力-Xcudafe
为我的警告找到匹配项。所以这里有另一种方式。
您可以将编译器标志传递给CL.exe
它将禁用特定警告。例如,要禁用有关未经检查的迭代器的警告,您可以通过/wd4996
.
warning C4996: 'std::_Copy_impl': Function call with parameters that may be
unsafe - this call relies on the caller to check that the passed values are
correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See
documentation on how to use Visual C++ 'Checked Iterators'
这里的棘手之处在于,默认情况下主机编译器设置中的参数不会传递给nvcc
,因此您需要通过CUDA C/C++
对话框添加它。
我将 nvcc 与 ubuntu g++ 编译器一起使用,在我的例子中是 openmpi mpic++。对于 g++ 编译器的“-Wunused-result”,相应的消息抑制是“-Wno-unused-result”。所以像 -Xcompiler "-Wno-unused-result" 这样在 nvcc 中传递它对我有用。