"M_PI" 和 "or" 的 nvcc 编译错误
nvcc compilation errors with "M_PI" and "or"
当试图编译这段代码时:
#define _USE_MATH_DEFINES
#include <cmath>
#include <cstdio>
void minimal_example(){
int i=2;
if(i==3 or i==4) printf("I want %d!\n",M_PI);
}
使用
nvcc -x cu -Xcompiler=/permissive- -dc cuda_nvcc_cl_test.cu -o cuda_nvcc_cl_test.obj
我得到以下错误(第 7 行):
error: expected a ")"
error: identifier "M_PI" is undefined
我正在使用 Windows 10 和 Visual Studio 的 cl.exe(x64 版本 19.16.27031.1)和 CUDA 工具包 10.1。
将 cmath
替换为 math.h
并将 or
替换为 ||
(或者添加 #include <ciso646>
)时,错误消失。但是,是否有一些编译器选项或其他可能性,以便我可以保持代码不变?
还有为什么 -Xcompiler=/permissive-
没有帮助?
这里有两个问题:
显然 nvcc
在解析您的代码之前包含 cmath
。正如已接受的答案 here 中所讨论的,如果您包含 cmath
并且此时没有实例化定义,您将不会得到 M_PI
定义,并且 随后包含的 cmath
不会解决这个问题,因为包含了守卫。一种可能的解决方法是将 -D_USE_MATH_DEFINES
添加到编译命令行。这从编译过程开始就将定义放在适当的位置,并且 M_PI
以这种方式定义。
与我所读的正确或标准行为相反,使用 or
代替 ||
似乎以包含 ciso646
为条件( on nvcc
on windows/visual only only. nvcc
on linux 似乎不需要这个)。是的,我知道它不应该那样工作,但它似乎是必要的。 This may be an issue with Visual Studio。如果愿意,您可以尝试使用 /Za
开关。 (我试了一下好像没什么用。)
使用 CUDA 10.1,在 VS2019 上,当我编译这个时:
#include <cstdio>
#include <ciso646>
void minimal_example(){
int i=2;
if(i==3 or i==4) printf("I want %f!\n",M_PI);
}
使用此命令行:
nvcc -x cu -dc test.cu -o test.obj -D_USE_MATH_DEFINES
我没有收到任何错误或警告。请注意,我还将您的 printf
格式说明符从 %d
更改为 %f
以与 M_PI
.
的类型一致
如果您真的不想包含 ciso646
、nvcc
supports 开关 -include
直接从命令行包含文件。因此我可以编译这个:
#include <cstdio>
void minimal_example(){
int i=2;
if(i==3 or i==4) printf("I want %f!\n",M_PI);
}
像这样:
nvcc -x cu -dc test.cu -o test.obj -D_USE_MATH_DEFINES -include ciso646
没有错误或警告。
当试图编译这段代码时:
#define _USE_MATH_DEFINES
#include <cmath>
#include <cstdio>
void minimal_example(){
int i=2;
if(i==3 or i==4) printf("I want %d!\n",M_PI);
}
使用
nvcc -x cu -Xcompiler=/permissive- -dc cuda_nvcc_cl_test.cu -o cuda_nvcc_cl_test.obj
我得到以下错误(第 7 行):
error: expected a ")"
error: identifier "M_PI" is undefined
我正在使用 Windows 10 和 Visual Studio 的 cl.exe(x64 版本 19.16.27031.1)和 CUDA 工具包 10.1。
将 cmath
替换为 math.h
并将 or
替换为 ||
(或者添加 #include <ciso646>
)时,错误消失。但是,是否有一些编译器选项或其他可能性,以便我可以保持代码不变?
还有为什么 -Xcompiler=/permissive-
没有帮助?
这里有两个问题:
显然
nvcc
在解析您的代码之前包含cmath
。正如已接受的答案 here 中所讨论的,如果您包含cmath
并且此时没有实例化定义,您将不会得到M_PI
定义,并且 随后包含的cmath
不会解决这个问题,因为包含了守卫。一种可能的解决方法是将-D_USE_MATH_DEFINES
添加到编译命令行。这从编译过程开始就将定义放在适当的位置,并且M_PI
以这种方式定义。与我所读的正确或标准行为相反,使用
or
代替||
似乎以包含ciso646
为条件( onnvcc
on windows/visual only only.nvcc
on linux 似乎不需要这个)。是的,我知道它不应该那样工作,但它似乎是必要的。 This may be an issue with Visual Studio。如果愿意,您可以尝试使用/Za
开关。 (我试了一下好像没什么用。)
使用 CUDA 10.1,在 VS2019 上,当我编译这个时:
#include <cstdio>
#include <ciso646>
void minimal_example(){
int i=2;
if(i==3 or i==4) printf("I want %f!\n",M_PI);
}
使用此命令行:
nvcc -x cu -dc test.cu -o test.obj -D_USE_MATH_DEFINES
我没有收到任何错误或警告。请注意,我还将您的 printf
格式说明符从 %d
更改为 %f
以与 M_PI
.
如果您真的不想包含 ciso646
、nvcc
supports 开关 -include
直接从命令行包含文件。因此我可以编译这个:
#include <cstdio>
void minimal_example(){
int i=2;
if(i==3 or i==4) printf("I want %f!\n",M_PI);
}
像这样:
nvcc -x cu -dc test.cu -o test.obj -D_USE_MATH_DEFINES -include ciso646
没有错误或警告。