#c #syntax #language-extension #gcc-extensions #gcc-statement-expression
#c #синтаксис #языковое расширение #gcc-extensions #gcc-statement-выражение
Вопрос:
Я наткнулся на эту странную программу на C .
#include <iostream>
using namespace std;
int main()
{
int a = ({int x; cin >> x; x;});
cout << a;
}
Кто-нибудь может объяснить, что происходит? Как называется эта конструкция?
Комментарии:
1. @VJo: Я имею в виду, как называется эта конструкция «({})»? Похоже ли это на анонимные функции?
2. 1 Черт возьми, я никогда этого раньше не видел. Жаль, что он специфичен для GNU C / C …
3. 1, немного похоже на лямбда-функцию 🙂
4. Мне только кажется, или в gcc больше странных нестандартных расширений, чем в любом другом компиляторе?
5. @David Да, он битком набит идиотами. Это то, что делает использование -pedantic почти необходимым.
Ответ №1:
Он присваивает введенное пользователем значение a
и распечатывает его. это делается с помощью Statement Expression
.
Выражения операторов являются расширением компилятора gnu gcc и не поддерживаются стандартами C / C . Следовательно, любой код, который использует выражение оператора, не соответствует стандарту и непереносим.
IBM XL C / C версии 7.0 также поддерживает выражения операторов, и в его документации они подробно объясняются:
Выражения операторов:
Составной оператор — это последовательность операторов, заключенных в фигурные скобки. В GNU C составной оператор внутри круглых скобок может отображаться как выражение в том, что называется
Statement expression
.
.--------------.
V |
>>-(--{----statement--;- --}--)--------------------------------><
Значение выражения оператора — это значение последнего простого выражения, которое появляется во всей конструкции. Если последний оператор не является выражением, то конструкция имеет тип void и не имеет значения.
Всегда компилируйте свой код, выбирая стандарт в GCC: используйте один из вариантов -ansi
, -std=c90
или -std=iso9899:1990
, -std=c 03
-std=c 0x
; чтобы получить всю диагностику, требуемую стандартом, вам также следует указать -pedantic
(или -pedantic-errors
, если вы хотите, чтобы это были ошибки, а не предупреждения).
Ответ №2:
Это расширение GCC. Скомпилируйте свой код с -pedantic
флагом, если вы хотите избавиться от подобных вещей (и вы действительно этого хотите).
Комментарии:
1. Я подозреваю, что это получило так много голосов, потому что многие люди почувствовали облегчение, узнав, что то, о чем они не слышали или не использовали, в любом случае не является стандартным.
Ответ №3:
Он создает встроенную область видимости, объявляет x
внутри нее, считывает ее из стандартного ввода, и весь оператор, наконец, вычисляется в x
, который присваивается a
.
Оператор запятой работает аналогично, хотя для этого не требуется отдельная область видимости. Например:
int x;
int a = (cin >> x, x);
сделал бы то же самое. Все операторы, соединенные запятыми, будут выполняться последовательно, и результат всего выражения будет установлен в значение крайнего правого операнда.
Комментарии:
1. Существует ли какое-либо конкретное имя для «({})»?
2. @Koshimitsu: Нет, потому что это комбинация операторов (если вы хотите их так называть). Фигурные скобки {} определяют начало ({) и конец (}) области видимости в этом случае. Обычные скобки предназначены только для того, чтобы инкапсулировать определение области видимости и возвращаемое значение. Я не совсем уверен, можно ли опустить эти обычные скобки в этом случае, однако я ожидаю, что они могут.
3. @Koshimitsu: Я не очень хорошо знаком с C , но в C это совершенно законно, и я использовал это много раз.
4. @Neil: ну, может быть, это потому, что gcc — единственный компилятор C, который я использую, поэтому я был введен в заблуждение.
Ответ №4:
Я не верю, что это стандартный C . Вероятно, это специфичное для компилятора расширение, которое позволяет внутренней области вычислять значение.