如何使C ++ 0x和__STRICT_ANSI__相处?

时间:2011-04-07 12:20:22

标签: c++ gcc c++11 mingw gnu

我需要在项目中使用popen,但我得到:

error: 'popen' was not declared in this scope

看起来GCC在__STRICT_ANSI__下定义-std=c++0x并且(与我能够找到的信息相反)-std=gnu++0x,导致popen(和{{ 1}})从_popen中删除。奇怪的是,取消定义stdio并没有解决问题,也没有向前宣布该功能。我显然错过了一些东西。有合理的解决方法吗?

我正在使用MinGW和4.5.0,并升级到4.5.2,但我仍然遇到同样的问题。我不想用msys来编译4.6.0,但如果必须的话,我会这样做。

3 个答案:

答案 0 :(得分:28)

我只是立即在命令行上取消它,这不是非常“干净”,但它可以正常工作。

-std=gnu++0x -U__STRICT_ANSI__

可能有一个很好的理由为什么不应该这样做,但它给了我想要的东西(C ++ 0x加上GNU扩展,加上传统的东西仍然有用)。我已经做了很长时间了,从来没有遇到过麻烦。但如果它吃了你的猫,不要怪我。

答案 1 :(得分:8)

我测试了MinGW gcc 4.6.1和gcc 4.7.0:它们都为__STRICT_ANSI__定义了-std=c++0x,但没有为-std=gnu++0x定义它。

答案 2 :(得分:2)

问题的简短回答

  

如何让C ++ 0x和__STRICT_ANSI__相处?

应该是:使用-std=gnu++0x代替-std=c++0x。这应该定义__STRICT_ANSI__ [1] ,因此您Makefile或构建环境中的其他内容可能仍会导致此问题定义 [2]

然后,正如其他人所指出的那样,一个(不太喜欢的)解决方法是使用命令行开关-U__STRICT_ANSI__取消定义。

请注意,为了指定为您的代码编写的C标准,-std=gnu++*将是典型的开关,而不是-std=c++*,只要您想要GNU扩展(在{{1 ,默认情况下启用GNU扩展,但如果指定gcc,则会禁用。

另一个说明;对于C,这是类似的:

-std=c++*

您可以获得所需C版本的语言支持,无论是否定义$ 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 (也可能存在其他差异)。


<强> [1]:

来自https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html

  

__ STRICT_ANSI __

     

当且仅当在调用GCC时指定-ansi开关或指定严格符合某些版本的ISO C或ISO C ++ 的-std开关时,GCC才定义此宏。它被定义为'1'。该宏的存在主要是为了指导GNU libc的头文件将它们的定义限制在1989 C标准中的最小集合。

这种情况很容易确认(在__STRICT_ANSI__ 4.8.2上运行):

gcc

[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) 转换的东西?这将产生-ansi,即使指定__STRICT_ANSI__,如文档中所述(参见上面的引文),并且可以轻松检查:

-std=gnu++*