g++: M_PI is visible in conforming mode
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
glibc (Ubuntu) |
New
|
Undecided
|
Unassigned |
Bug Description
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.
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 g++ and/or
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.)
Output illustrating the problem follows:
$ lsb_release -rd
Description: Ubuntu 18.04.1 LTS
Release: 18.04
$ uname -a
Linux bomb20 4.15.0-42-generic #45-Ubuntu SMP Thu Nov 15 19:32:57 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
$ dpkg -l g++ clang libc6-dev:amd64 | grep '^ii'
ii clang 1:6.0-41~
ii g++ 4:7.3.0-3ubuntu2.1 amd64 GNU C++ compiler
ii libc6-dev:amd64 2.27-3ubuntu1 amd64 GNU C Library: Development Libraries and Header Files
$ g++ --version | head -1
g++ (Ubuntu 7.3.0-27ubuntu1
$ clang++ --version
clang version 6.0.0-1ubuntu2 (tags/RELEASE_
Target: x86_64-pc-linux-gnu
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 -c M_PI_bug.cpp
In file included from /usr/include/
M_PI_bug.cpp: In function ‘int main()’:
M_PI_bug.cpp:4:15: error: expected unqualified-id before numeric constant
const int M_PI = 22/7;
^
$ clang++ -std=c++17 -pedantic-errors -c M_PI_bug.cpp
M_PI_bug.cpp:4:15: error: expected unqualified-id
const int M_PI = 22/7;
^
/usr/include/
# define M_PI 3.1415926535897
1 error generated.