clang++: M_PI is visible in conforming mode

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view

clang++: M_PI is visible in conforming mode

Keith Thompson
The macro M_PI, which expands to a constant approximating the value
of pi, is defined by POSIX, but not by ISO C or ISO C++.  It is
not a reserved identifier, so it should be available for use as a
user-defined identifier.

The problem: Including <cmath> causes M_PI to be defined, even when
the C++ compiler is invoked in what should be a conforming mode.

This problem occurs with clang++.  It does not occur with g++.

EXPECTED: Program compiles without error and prints "3".
OBSERVED: Program is rejected at compile time.

(The program is rejected when g++ or clang++ is invoked without
options.  That's not a bug.)

Using <math.h> rather than <cmath> doesn't change the symptom.

A similar program in C does not exhibit the problem.

I *think* the problem is in the "math.h" header, which should arrange
for M_PI and similar macros not to be defined in conforming mode.
It's also possible that a fix might involve updates to clang++.
I haven't fully investigated the twisty maze of macro definitions
and nested #includes in math.h.

(I acknowledge that writing your own definition of M_PI is not a
good idea, and that the definition in this program is particularly
poor style.)

I'm using 64-bit Cygwin on Windows 10, with all the latest updates.

See also
a report for a similar bug on Ubuntu (affecting both g++ and clang++).

Output illustrating the problem follows:

$ uname -a
CYGWIN_NT-10.0 eddie 2.11.2(0.329/5/3) 2018-11-08 14:34 x86_64 Cygwin

$ clang++ --version
clang version 5.0.1 (tags/RELEASE_501/final)
Target: x86_64-unknown-windows-cygnus
Thread model: posix
InstalledDir: /usr/bin

$ cat M_PI_bug.cpp
#include <iostream>
#include <cmath>
int main() {
    const int M_PI = 22/7;
    std::cout << M_PI << '\n';

// This is not reasonable code.
// The issue is that a conforming C++ compiler must accept it.

// Expected output: 3

$ g++ -std=c++17 -pedantic-errors M_PI_bug.cpp && ./M_PI_BUG

$ clang++ -std=c++17 -pedantic-errors M_PI_bug.cpp && ./M_PI_BUG
M_PI_bug.cpp:4:15: error: expected unqualified-id
    const int M_PI = 22/7;
/usr/include/math.h:617:15: note: expanded from macro 'M_PI'
#define M_PI            3.14159265358979323846
1 error generated.

Problem reports:
Unsubscribe info: