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.
M_PIis also defined incmathvia include ofmath.h