24

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.

Jon Purdy
  • 53,300
  • 8
  • 96
  • 166

3 Answers3

29

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.

Damon
  • 67,688
  • 20
  • 135
  • 185
  • 1
    Whaddaya know, that does it. I actually had some conflicting settings elsewhere in my environment that were causing mischief. – Jon Purdy Apr 07 '11 at 12:51
  • 1
    Yeah, been there before... totally annoying. Easiest thing I found to save pain was to simply add the above to the IDE's global compiler options. Admittedly, it's not the prettiest thing on earth, but I've never had a build (neither my own, nor third party stuff) fail again due to this problem thereafter. – Damon Apr 07 '11 at 13:14
  • 2
    +1 Same thing with gcc 4.5.3 under Cygwin. Alas, with `__STRICT_ANSI__` vital functions like `vsnprintf` are not defined. Obviously, the gcc maintainers do not compile their test suite with all possible `-std=xxx`'s, as it ought to be. – Andreas Spindler Oct 09 '12 at 13:41
  • 1
    @AndreasSpindler: This is not a GCC problem but headers problem, I think. Cygwin headers defining `vsnprintf()` are not coming from GCC. – wilx Mar 01 '14 at 07:38
  • @Damon: Could you show how to use this method ? I want to install **ACADOtoolkit**, which an optimization package, which after `cmake ..` and then subsequently on `make` gives me this error (popen ...). I tried adding the flags you showed to the make command, but it doesnt'w work that way. How and where do I add the line ? – Chintan Pathak Nov 24 '15 at 04:08
  • @ChintanPathak: Not using cmake if I can avoid doing so, since I loathe it -- so, I'm not precisely an expert on that one! But I guess something like `set(CMAKE_CXX_FLAGS "-std=c++11 -U__STRICT_ANSI__")` inside `CMakeLists.txt` will do. Not sure if cmake respects environment variables like `CFLAGS` or `CPPFLAGS`, if that is the case you could just set that one prior to invoking it, too. – Damon Nov 24 '15 at 09:44
9

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.

kkoehne
  • 91
  • 1
  • 1
4

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
Carl
  • 937
  • 10
  • 21