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

hyperknot picture hyperknot · Jul 3, 2011 · Viewed 139k times · Source

I am using Visual Studio 2010. I have read that in C++ it is better to use <cmath> rather than <math.h>.

But in the program I am trying to write (Win32 console application, empty project) if I write:

#define _USE_MATH_DEFINES
#include <math.h>

it compiles, while if I write

#define _USE_MATH_DEFINES
#include <cmath>

it fails with

error C2065: 'M_PI' : undeclared identifier

Is it normal? Does it matter if I use cmath or math.h? If yes, how can I make it work with cmath?

UPDATE: if I define _USE_MATH_DEFINES in the GUI, it works. Any clue why this is happening?

Answer

Goz picture Goz · Jul 3, 2011

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 :)