How can I make C++0x and __STRICT_ANSI__ get along?
I need to use popen
in a project, but I get:
error: 'popen' was not declared in this scope
It looks like GCC defines __STRICT_ANSI__
under both -std=c++0x
and (contrary to what little information I was able to find) 开发者_如何转开发-std=gnu++0x
, which causes popen
(and _popen
) to be elided from stdio
. Oddly enough, undefining __STRICT_ANSI__
doesn't solve the issue, nor does forward-declaring the function. I'm obviously missing something. Is there a reasonable workaround?
I was using MinGW with 4.5.0, and upgraded to 4.5.2, but am still experiencing the same problem. I'd rather not have to muck about with msys to compile 4.6.0, but I will if I must.
I'm simply undefining it on the commandline right away, this is not terribly "clean" but it works fine from what I can tell.
-std=gnu++0x -U__STRICT_ANSI__
There is probably a good reason why one should not do that, but it gives me what I want (C++0x plus GNU extensions, plus legacy stuff still works). I've been doing this for a long time and never run into trouble. But don't blame me if it eats your cat.
I tested both MinGW gcc 4.6.1 and gcc 4.7.0: They both do define __STRICT_ANSI__
for -std=c++0x
, but do not define it for -std=gnu++0x
.
The short answer to the question
How can I make C++0x and __STRICT_ANSI__ get along?
should be: use -std=gnu++0x
instead of -std=c++0x
. This should not define __STRICT_ANSI__
[1], so there's probably something else in you Makefile
or build environment that still causes this to be defined [2].
A (less-prefered) work-around then, as pointed out by others, would be to un-define it with a command-line switch -U__STRICT_ANSI__
.
Note that for specifying which C standard your code is written for, -std=gnu++*
would be the typical switch to use, rather than -std=c++*
, as long as you want the GNU extensions (in gcc
, the GNU extensions are enabled by default, but will be disabled if you specify -std=c++*
).
Another note; for C, this is similar:
$ touch empty.c
$ gcc -std=c99 -E -dM empty.c | grep '\(__STRICT\|__STDC_V\)'
#define __STRICT_ANSI__ 1
#define __STDC_VERSION__ 199901L
$ gcc -std=gnu99 -E -dM empty.c | grep '\(__STRICT\|__STDC_V\)'
#define __STDC_VERSION__ 199901L
You'll get language support for the desired C version, with or without __STRICT_ANSI__
defined (there are possibly other differences as well).
[1]:
From https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html:
__STRICT_ANSI__
GCC defines this macro if and only if the -ansi switch, or a -std switch specifying strict conformance to some version of ISO C or ISO C++, was specified when GCC was invoked. It is defined to ‘1’. This macro exists primarily to direct GNU libc's header files to restrict their definitions to the minimal set found in the 1989 C standard.
That this is the case can easily be confirmed (run on gcc
4.8.2):
$ touch empty.cpp
$ gcc -std=c++0x -E -dM empty.cpp | grep '__STRICT'
#define __STRICT_ANSI__ 1
$ gcc -std=gnu++0x -E -dM empty.cpp | grep '__STRICT'
$ # (no match)
[2]: Something adding an -ansi
switch perhaps? This will yield the __STRICT_ANSI__
, even if specifying -std=gnu++*
, as is stated by the documentation (see citation above), and can easily be checked:
$ gcc -std=gnu++0x -E -dM -ansi empty.cpp | grep '__STRICT'
#define __STRICT_ANSI__ 1
精彩评论