14

I noticed M_PI is unavailable on c11. By looking at /usr/include/math.h I can see M_PI is defined if:

#if !defined(__STRICT_ANSI__) || ((_XOPEN_SOURCE - 0) >= 500)
...
#define M_PI 3.1415...
#endif 

Moreover in the math.h from glibc __STRICT_ANSI__ is replaced with __USE_MISC. I am completely lost with this.

What is the story in between --std=c11 and the constants defined in math.h?

Which libc should I consider on a debian distribution ?

By the way, M_PI is defined in c99 and gnu11...

2
  • Why do you have the c++11 tag if what you ask is clearly about C11 and not C++11? Commented Mar 25, 2015 at 19:15
  • 2
    Yes there is, and your post was already edited to have the c11 tag instead of c++11. Commented Mar 25, 2015 at 19:22

3 Answers 3

26

It's simple: M_PI is not defined in standard C. Provide your own definition if you want to be standard-compliant.

C compilers cannot introduce such constants without breaking legal C programs (the name is not reserved, and could be used as an identifier), and as such, they are only defined as an extension.

GCC 4.9 when used with -std=c99 doesn't define M_PI, but does when used with -std=gnu99

Sign up to request clarification or add additional context in comments.

7 Comments

It was defined in 'c99' though.
@coin It shouldn't be - C99 also doesn't define M_PI.
The default of GCC is gnu90. 5.1.0 (not released yet) will default to gnu11.
@coin: It uses the same libc as with different or without -std options (which usually is glibc, but doesn't have to be. E.g. on Windows). Also read man7.org/linux/man-pages/man7/feature_test_macros.7.html and gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html for more information.
@coin Why bother? Either you want more stuff, then you use -std=gnu99 with extensions, or you don't want extensions because you want portability and don't want to accidentally limit yourself to a single compiler, in that case you use -std=c99.
|
11

If you just want M_PI while looking for a more comprehensive answer with POSIX / XOPEN feature tests macros, etc., an interim solution is:

#ifndef M_PI
#define M_PI (3.14159265358979323846)
#endif

That's "1.20" format, which is also sufficient for 'round-trip' representation for an 80 bit extended type. double precision is "1.16". For 128-bit quad precision:

#define M_PI (3.14159265358979323846264338327950288)

The "1.35" format for round-trip precision. This means if you want to print out a floating point double, and recover the same value when you read it back, you should use "%+1.16" for printf functions, as so on. You might say that a double doesn't have 17 significant digits, but those digits are not 'junk' if you want to recover a value.

Anyway - there are better resources than this available.

2 Comments

For correct 1.16 --> +1. BTW: See any downside to having lots of PI digits like 80 digits?
@chux - not that I can think of. gcc at least includes the gmp / mpfr / mpc libraries to take care of all multiple-precision issues, with correct (and selectable) rounding modes, etc. If an 80 digit PI value was assigned to a single precision float, I would expect it to do the right thing. Don't know how up to date this page is. I don't know clang's approach.
3

The M_PI macro isn't defined by the C11 standard: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf

Therefore, the #if guards are protecting you from problems in case you want to define your own M_PI macro. gcc is doing exactly the right thing. The standard headers shouldn't arbitrarily define macros that are not in the standard.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.