Reputation: 237
When trying to compile this piece of code:
#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);
}
using
nvcc -x cu -Xcompiler=/permissive- -dc cuda_nvcc_cl_test.cu -o cuda_nvcc_cl_test.obj
I get the follwing errors (in line 7):
error: expected a ")"
error: identifier "M_PI" is undefined
I am using Windows 10 with Visual Studio's cl.exe (Version 19.16.27031.1 for x64) and CUDA toolkit 10.1.
When replacing cmath
with math.h
and or
with ||
(alternatively add #include <ciso646>
), the errors disappear. However, are there some compiler options or other possibilities so that I can keep the code as is?
Also why did -Xcompiler=/permissive-
not help?
Upvotes: 0
Views: 1188
Reputation: 151799
There are 2 issues here:
Apparently nvcc
includes cmath
prior to parsing your code. As discussed in the accepted answer here, if you include cmath
and you don't have the define instantiated at that point, you won't get M_PI
defined, and subsequent inclusions of cmath
won't fix this, due to include guards. A possible workaround for this is to add -D_USE_MATH_DEFINES
to your compile command line. This puts the define in place from the start of the compilation process, and M_PI
gets defined that way.
Contrary to what I read as correct or standard behavior, the use of or
in place of ||
seems to be conditioned on inclusion of ciso646
(on nvcc
on windows/visual studio only. nvcc
on linux doesn't seem to need this). Yes, I understand it is not supposed to work that way, but nevertheless it appears to be necessary. This may be an issue with Visual Studio. You can experiment with the /Za
switch if you like. (It didn't seem to help when I tried it.)
With CUDA 10.1, on VS2019, when I compile this:
#include <cstdio>
#include <ciso646>
void minimal_example(){
int i=2;
if(i==3 or i==4) printf("I want %f!\n",M_PI);
}
with this command line:
nvcc -x cu -dc test.cu -o test.obj -D_USE_MATH_DEFINES
I get no errors or warnings. Note that I have also changed your printf
format specifier from %d
to %f
to be consistent with the type of M_PI
.
If you really don't want to include ciso646
, nvcc
supports the -include
switch to include a file directly from the command line. Therefore I can compile this:
#include <cstdio>
void minimal_example(){
int i=2;
if(i==3 or i==4) printf("I want %f!\n",M_PI);
}
like this:
nvcc -x cu -dc test.cu -o test.obj -D_USE_MATH_DEFINES -include ciso646
with no errors or warnings.
Upvotes: 2