Подтвердить что ты не робот

Как я могу заставить С++ 0x и __STRICT_ANSI__ ладить?

Мне нужно использовать popen в проекте, но я получаю:

error: 'popen' was not declared in this scope

Похоже, что GCC определяет __STRICT_ANSI__ под -std=c++0x и (вопреки тому, какую небольшую информацию я смог найти) -std=gnu++0x, что приводит к тому, что popen_popen) отклоняется от stdio > . Как ни странно, undefining __STRICT_ANSI__ не решает проблему, а также не сообщает об объявлении функции. Я, очевидно, что-то пропустил. Существует ли разумное решение?

Я использовал MinGW с 4.5.0 и обновлялся до 4.5.2, но я все еще испытываю ту же проблему. Я бы предпочел не гадать с msys компилировать 4.6.0, но я буду, если я должен.

4b9b3361

Ответ 1

Я просто сразу определяю его на командной строке, это не ужасно "чисто", но он отлично работает, что я могу сказать.

-std=gnu++0x -U__STRICT_ANSI__

Вероятно, есть веская причина, почему этого не следует делать, но он дает мне то, что я хочу (С++ 0x плюс расширения GNU, плюс устаревший материал все еще работает). Я делаю это в течение долгого времени и никогда не сталкивался с проблемами. Но не обвиняйте меня, если он ест вашу кошку.

Ответ 2

Я тестировал как MinGW gcc 4.6.1, так и gcc 4.7.0: оба они определяют __STRICT_ANSI__ для -std=c++0x, но не определяют его для -std=gnu++0x.

Ответ 3

Короткий ответ на вопрос

Как я могу заставить С++ 0x и __STRICT_ANSI__ ладить?

должен быть: используйте -std=gnu++0x вместо -std=c++0x. Это не должно указывать __STRICT_ANSI__ [1], поэтому в вас может быть что-то еще Makefile или среда сборки, которая все еще вызывает это определение [2].

A (менее предпочтительный), тогда, как указывалось другими, было бы определить его с помощью командной строки -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 или переключатель -std, указывающий строгое соответствие некоторой версии ISO C или ISO С++. Он определен как '1. Этот макрос существует в основном для прямого заголовка файлов GNU libc, чтобы ограничить их определения минимальным набором, найденным в стандарте C. 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