Как я могу заставить C ++ 0x и __STRICT_ANSI__ ладить? - PullRequest
23 голосов
/ 07 апреля 2011

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

error: 'popen' was not declared in this scope

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

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

Ответы [ 3 ]

28 голосов
/ 07 апреля 2011

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

-std=gnu++0x -U__STRICT_ANSI__

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

8 голосов
/ 06 сентября 2012

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

3 голосов
/ 01 апреля 2015

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

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

То, что это так, можно легко подтвердить (запустить на 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
...