Reader Chris pointed out a fun and common C language inconsistency in last week’s Lesson: The constant
M_PI isn’t always available. It’s not defined as part of the C standard, which means your compiler may lack this handy shortcut, located in the
math.h header file. What to do, what to do?
One of the problems with “standards” in the computer industry is that they are anything but standards. Some exist historically, but are never officially declared. And then you have Microsoft, which declares industry standards that only Microsoft adheres to. It’s a mess.
With C, the primary standard is ANSI. The most recent versions are C99 (1999) and C11 (2011). The GNU standard also exists, implemented in the ubiquitous gcc compiler. Going back further is the K&R standard, based on C as documented in Kernighan and Ritchie’s book, The C Programming Language, aka “the manual.”
In the GNU standard, many constants are declared in the
math.h header file, including
The C99 standard doesn’t specify
M_PI, neither does C11. Its absence doesn’t imply that it’s illegal to use the
M_PI constant, just that a programmer shouldn’t assume that
M_PI is available in all compilers.
To resolve this issue in your code, add the following preprocessor instructions in addition to including the
math.h header file:
#ifndef M_PI #define M_PI (3.14159265358979323846264338327950288) #endif /* M_PI */
#ifndef preprocessor directive resolves as TRUE when
M_PI is unavailable. If so, the next line defines the constant. The
#endif directive closes the statements. When
M_PI is defined, the other two statements are skipped. (Click here to read more about preprocessor directives.)
It doesn’t hurt to add this type of checking for any constant you use, especially for code you plan on releasing into the wild.
Another problem exists when functions are available in some libraries but not others. For example, the random() function is available in clang, but not in gcc (at least the last time I checked). If you’re practicing on your own, overlooking what’s standard and what’s not is okay. But when you must write a program and distribute its source, ensure that you check for all possibilities, confirm what’s standard and what’s not, and provide resolutions in your code for what’s unavailable.