开发者

How can I make C++0x and __STRICT_ANSI__ get along?

开发者 https://www.devze.com 2023-02-23 06:36 出处:网络
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 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
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号