Как я могу заставить С++ 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, но я буду, если я должен.
Ответы
Ответ 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