Macro DOMAIN
in math.h collides with enums and possibly other types. I don't know what to make of it.
#include <algorithm>
enum Type { DOMAIN };
int main(){
Type t = Type::DOMAIN;
return 0;
}
Compile with flag -std=c++11. The C99 version of this code compiles perfectly fine though:
#include <algorithm>
enum Type { DOMAIN };
int main(){
Type t = DOMAIN;
return 0;
}
I checked the source code and the library is to blame. algorithm includes stl_algo.h, in which there is ifdef:
#if __cplusplus >= 201103L
#include <random> // for std::uniform_int_distribution
#include <functional> // for std::bind
#endif
The following code compiles fine on c++11 compiler:
#include <random>
#include <iostream>
int main(){
std::cout << DOMAIN << std::endl;
return 0;
}
Is it a feature or a bug?
#ifdef DOMAIN
#undef DOMAIN
#endif
It's a bug (or a "wart" if you want to be generous).
All the rest of this answer refers only to GCC and the Gnu standard C library headers. The man
page references are to a linux system (but I've added links to man7.org).
The DOMAIN
macro comes from math.h
's System V support. (See man matherr
.) System V support is normally enabled by defining the _SVID_SOURCE
feature-test macro (see man feature_test_macros
), but it is enabled along with a raft of other extensions if _GNU_SOURCE
is defined, or by default if no feature test macros are defined.
gcc
predefines _GNU_SOURCE
for C programs if the --std
option is omitted or set to gnu##
. The various --std=c##
options cause __STRICT_ANSI__
to be defined. Consequently, compiling C code with some explicit C standard will suppress the System V extensions. That needs to be done because the System V extensions are not standards-compatible, not even with Posix, because they pollute the global namespace. (DOMAIN
is just one example of this pollution.)
However, g++
defines _GNU_SOURCE
even if --std=c++##
is specified, and consequently the System V extensions will sneak in. (Thanks to @dyp for the link to this libstdc++ FAQ entry. and this long and inconclusive discussion from 2001 on the GCC mailing list)
An ugly workaround is to set up the features yourself, and then undefine __USE_SVID
:
#include <features.h>
#undef __USE_SVID
#include <random>
#include <iostream>
int main(){
std::cout << DOMAIN << std::endl;
return 0;
}
(Live on coliru)
IMHO, this should not be necessary. But there it is.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With