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

发布于 2024-10-31 03:31:59 字数 403 浏览 1 评论 0原文

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

error: 'popen' was not declared in this scope

看起来 GCC 在 -std=c++0x 和(与我能找到的少量信息相反)-std=gnu++0x,这会导致popen(和_popen)从 stdio 中删除。奇怪的是,取消定义 __STRICT_ANSI__ 并不能解决问题,前向声明函数也不能解决问题。我显然错过了一些东西。有没有合理的解决办法?

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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

匿名。 2024-11-07 03:31:59

我只是立即在命令行上取消定义它,这并不是非常“干净”,但据我所知,它工作得很好。

-std=gnu++0x -U__STRICT_ANSI__

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

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.

三生路 2024-11-07 03:31:59

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

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.

ヤ经典坏疍 2024-11-07 03:31:59

问题的简短回答

如何让 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 时指定了 -ansi 开关或指定严格符合某些版本的 ISO C 或 ISO C++ 的 -std 开关时,GCC 才会定义此宏。它被定义为“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 开关?即使指定 -std=gnu++*,这也会产生 __STRICT_ANSI__,如文档所述(请参阅上面的引用),并且可以轻松检查:

$ gcc -std=gnu++0x -E -dM -ansi empty.cpp | grep '__STRICT'
#define __STRICT_ANSI__ 1

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文