我怎样才能让 C++0x 和 __STRICT_ANSI__ 相处融洽?
Posted
技术标签:
【中文标题】我怎样才能让 C++0x 和 __STRICT_ANSI__ 相处融洽?【英文标题】:How can I make C++0x and __STRICT_ANSI__ get along? 【发布时间】:2011-04-07 12:20:22 【问题描述】:我需要在项目中使用popen
,但我得到:
错误:'popen' 未在此范围内声明
看起来 GCC 在 -std=c++0x
和(与我能找到的少量信息相反)-std=gnu++0x
下定义了 __STRICT_ANSI__
,这导致 popen
(和 _popen
)从 @987654327 中删除@。奇怪的是,取消定义 __STRICT_ANSI__
并不能解决问题,也不能前向声明函数。我显然错过了一些东西。是否有合理的解决方法?
我使用 4.5.0 的 MinGW,并升级到 4.5.2,但仍然遇到同样的问题。我宁愿不用 msys 来编译 4.6.0,但如果必须的话,我会这样做。
【问题讨论】:
【参考方案1】:我只是立即在命令行上取消定义它,这不是非常“干净”,但据我所知它工作正常。
-std=gnu++0x -U__STRICT_ANSI__
不应该这样做可能是有充分理由的,但它给了我想要的东西(C++0x 加上 GNU 扩展,加上遗留的东西仍然有效)。我已经这样做了很长时间,从来没有遇到过麻烦。但是如果它吃了你的猫,别怪我。
【讨论】:
什么都知道,就是这样。实际上,我在环境中的其他地方有一些相互冲突的设置,导致了恶作剧。 是的,以前去过那里...完全烦人。我发现最简单的方法是简单地将上述内容添加到 IDE 的全局编译器选项中。诚然,这不是地球上最漂亮的东西,但我从来没有因为这个问题而再次失败(无论是我自己的,也不是第三方的)。 +1 与 Cygwin 下的 gcc 4.5.3 相同。唉,__STRICT_ANSI__
像 vsnprintf
这样的重要功能没有定义。显然,gcc 维护者并没有按照所有可能的-std=xxx
编译他们的测试套件,因为它应该是。
@AndreasSpindler:我认为这不是 GCC 问题,而是标题问题。定义 vsnprintf()
的 Cygwin 标头并非来自 GCC。
@Damon:你能展示一下如何使用这个方法吗?我想安装 ACDOtoolkit,它是一个优化包,在cmake ..
之后,然后在make
上给我这个错误(popen ...)。我尝试将您显示的标志添加到 make 命令,但它不会那样工作。如何以及在何处添加该行?【参考方案2】:
我测试了 MinGW gcc 4.6.1 和 gcc 4.7.0:它们都为-std=c++0x
定义了__STRICT_ANSI__
,但没有为-std=gnu++0x
定义它。
【讨论】:
如果有人想知道,c++11
和 gnu++11
也是如此。【参考方案3】:
问题的简短回答
如何让 C++0x 和 __STRICT_ANSI__ 相处融洽?
应该是:使用-std=gnu++0x
而不是-std=c++0x
。这应该不定义__STRICT_ANSI__
[1],所以你可能有其他东西Makefile
或构建环境仍然导致它被定义[2 ]。
正如其他人所指出的那样,一个(不太受欢迎的)解决方法是使用命令行开关 -U__STRICT_ANSI__
取消定义它。
请注意,为了指定您的代码是针对哪个 C 标准编写的,-std=gnu++*
将是使用的典型开关,而不是 -std=c++*
,只要您想要 GNU 扩展(在 gcc
中,GNU 扩展默认启用,但如果您指定-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
您将获得所需 C 版本的语言支持,无论是否定义了 __STRICT_ANSI__
(也可能存在其他差异)。
[1]:
来自https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html:
__STRICT_ANSI__
GCC 定义此宏当且仅当在调用 GCC 时指定了 -ansi 开关或指定严格符合 ISO C 或 ISO C++ 的某些版本的 -std 开关。它被定义为“1”。这个宏的存在主要是为了指导 GNU libc 的头文件将它们的定义限制在 1989 C 标准中的最小集合。
这种情况很容易得到确认(在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]: 可能添加了-ansi
开关?这将产生__STRICT_ANSI__
,即使指定-std=gnu++*
,如文档所述(参见上面的引用),并且可以很容易地检查:
$ gcc -std=gnu++0x -E -dM -ansi empty.cpp | grep '__STRICT'
#define __STRICT_ANSI__ 1
【讨论】:
以上是关于我怎样才能让 C++0x 和 __STRICT_ANSI__ 相处融洽?的主要内容,如果未能解决你的问题,请参考以下文章
我怎样才能让 QLabel 与它显示的 QPixmap 的大小完全一致?