M_Pi Works with Math.H But Not with Cmath in Visual Studio

M_PI works with math.h but not with cmath in Visual Studio

Interestingly I checked this on an app of mine and I got the same error.

I spent a while checking through headers to see if there was anything undef'ing the _USE_MATH_DEFINES and found nothing.

So I moved the

#define _USE_MATH_DEFINES
#include <cmath>

to be the first thing in my file (I don't use PCHs so if you are you will have to have it after the #include "stdafx.h") and suddenly it compile perfectly.

Try moving it higher up the page. Totally unsure as to why this would cause issues though.

Edit: Figured it out. The #include <math.h> occurs within cmath's header guards. This means that something higher up the list of #includes is including cmath without the #define specified. math.h is specifically designed so that you can include it again with that define now changed to add M_PI etc. This is NOT the case with cmath. So you need to make sure you #define _USE_MATH_DEFINES before you include anything else. Hope that clears it up for you :)

Failing that just include math.h you are using non-standard C/C++ as already pointed out :)

Edit 2: Or as David points out in the comments just make yourself a constant that defines the value and you have something more portable anyway :)

M_PI works with math.h but not with cmath in Visual Studio

Interestingly I checked this on an app of mine and I got the same error.

I spent a while checking through headers to see if there was anything undef'ing the _USE_MATH_DEFINES and found nothing.

So I moved the

#define _USE_MATH_DEFINES
#include <cmath>

to be the first thing in my file (I don't use PCHs so if you are you will have to have it after the #include "stdafx.h") and suddenly it compile perfectly.

Try moving it higher up the page. Totally unsure as to why this would cause issues though.

Edit: Figured it out. The #include <math.h> occurs within cmath's header guards. This means that something higher up the list of #includes is including cmath without the #define specified. math.h is specifically designed so that you can include it again with that define now changed to add M_PI etc. This is NOT the case with cmath. So you need to make sure you #define _USE_MATH_DEFINES before you include anything else. Hope that clears it up for you :)

Failing that just include math.h you are using non-standard C/C++ as already pointed out :)

Edit 2: Or as David points out in the comments just make yourself a constant that defines the value and you have something more portable anyway :)

VS2017 'M_PI': undeclared identifier

This is a known issue, try defining _USE_MATH_DEFINES as a definition in your project properties instead of the file itself.

This can be found in project properties -> C/C++ -> Preprocessor -> Preprocessor definitions.

M_PI works with math.h but not with cmath in Visual Studio

Interestingly I checked this on an app of mine and I got the same error.

I spent a while checking through headers to see if there was anything undef'ing the _USE_MATH_DEFINES and found nothing.

So I moved the

#define _USE_MATH_DEFINES
#include <cmath>

to be the first thing in my file (I don't use PCHs so if you are you will have to have it after the #include "stdafx.h") and suddenly it compile perfectly.

Try moving it higher up the page. Totally unsure as to why this would cause issues though.

Edit: Figured it out. The #include <math.h> occurs within cmath's header guards. This means that something higher up the list of #includes is including cmath without the #define specified. math.h is specifically designed so that you can include it again with that define now changed to add M_PI etc. This is NOT the case with cmath. So you need to make sure you #define _USE_MATH_DEFINES before you include anything else. Hope that clears it up for you :)

Failing that just include math.h you are using non-standard C/C++ as already pointed out :)

Edit 2: Or as David points out in the comments just make yourself a constant that defines the value and you have something more portable anyway :)

nvcc compilation errors with M_PI and or

There are 2 issues here:

  1. 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.

  2. 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.

How to use the PI constant in C++

On some (especially older) platforms (see the comments below) you might need to

#define _USE_MATH_DEFINES

and then include the necessary header file:

#include <math.h>

and the value of pi can be accessed via:

M_PI

In my math.h (2014) it is defined as:

# define M_PI           3.14159265358979323846  /* pi */

but check your math.h for more. An extract from the "old" math.h (in 2009):

/* Define _USE_MATH_DEFINES before including math.h to expose these macro
* definitions for common math constants. These are placed under an #ifdef
* since these commonly-defined names are not part of the C/C++ standards.
*/

However:

  1. on newer platforms (at least on my 64 bit Ubuntu 14.04) I do not need to define the _USE_MATH_DEFINES

  2. On (recent) Linux platforms there are long double values too provided as a GNU Extension:

    # define M_PIl          3.141592653589793238462643383279502884L /* pi */

How do I access math constants (eg. M_PI) in Visual C++ 2008?

They are, but you also need to #define _USE_MATH_DEFINES before you #include <cmath>

Is cmath or math.h really needed? Compiles without it

As you've noticed, the code snippet you provided works in Visual Studio but not with other compilers. This is because of how the standard library is implemented for each compiler.

It turns out that when you include Visual Studio's implementation of <iostream>, you end up including a bunch of other headers indirectly, and one of these headers is <cmath>.

To see the exact chain, navigate to the standard library include directory. For me (I use Visual Studio 2013 Community Edition) this is located at

C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include

  1. Open iostream. Note the line #include <istream>
  2. Open istream. Note the line #include <ostream>
  3. Open ostream. Note the line #include <ios>
  4. Open ios. Note the line #include <xlocnum>
  5. Open xlocnum. Note the line #include <cmath>

Guess what? You included cmath when you included iostream... so your code is good to go, on Visual Studio at least. But, don't rely on implementation details or your code will break if you try to migrate it to another platform/toolchain.

For example, trying to compile the provided snippet using g++ on Cygwin results in the following error:

temp.cpp: In function ‘int main()’:
temp.cpp:22:34: error: ‘log10’ was not declared in this scope
double pH = -log10(mc);

This must mean g++'s implementation of <iostream> doesn't depend on <cmath>



Related Topics



Leave a reply



Submit