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

В каких версиях C есть блок внутри скобок, используемый для возврата значения?

Если я это сделаю:

int j = ({int x = 7; x+3;});

В i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5646) gcc компилируется просто отлично. Этот блок ({int x = 7; x+3;}) возвращает значение последнего оператора как значение блока. Если вы удалите скобку, она не компилируется. Могу ли я ожидать, что это будет работать в большинстве компиляторов C?

Кроме того, какое имя для этой конструкции? У меня было много проблем в поиске, потому что поисковые системы не индексируют () или {}, а C - ужасный поисковый запрос. Я также не смог найти ничего об этом в любой из моих книг, возможно, потому, что я не знаю, что искать.

4b9b3361

Ответ 1

Если вы удалите скобку, она не компилируется.

Без круглых скобок компилятор будет рассматривать это как блок агрегатной инициализации и сработает, когда увидит ключевое слово int. Вы не можете использовать ключевые слова в блоках инициализации.

6.7.8 Инициализация

11 Инициализатор для скаляра должен быть единственным выражением, необязательно заключенным в фигурные скобки. начальное значение объекта - это выражение (после преобразования); тот же тип ограничения и преобразования, как для простого присваивания, принимая тип скаляра быть неквалифицированной версией его объявленного типа.

6.2.5 Типы

21 Арифметические типы и типы указателей в совокупности называются скалярными типами. Массив и типы структуры совместно называются агрегатными типами.


Можно ли ожидать, что это будет работать в большинстве компиляторов c?

Нет. Похоже на нестандартное расширение GNU.

Кроме того, какое имя для этой конструкции?

Интересно, есть ли какие-то. Собственно, это похоже на то, что обычно делают макросы.

Ответ 2

Это aa расширение GCC:

Составной оператор, заключенный в круглые скобки, может отображаться как выражение в GNU C. Это позволяет использовать в выражении циклы, переключатели и локальные переменные.

Напомним, что составной оператор представляет собой последовательность утверждений, окруженных фигурными скобками; в этой конструкции круглые скобки охватывают фигурные скобки. Например:

 ({ int y = foo (); int z;
    if (y > 0) z = y;
    else z = - y;
    z; })

является действительным (хотя и немного более сложным, чем необходимо) выражением для абсолютного значения foo ().

Последнее в составном выражении должно быть выражением, за которым следует точка с запятой; значение этого подвыражения служит значением всей конструкции. (Если вы используете какой-то другой оператор, последний в фигурных скобках, у конструкции есть тип void и, следовательно, фактически нет значения.)...

Ответ 3

Вы можете ожидать, что он будет работать в большинстве версий GCC.

Вы можете ожидать, что он будет работать почти нигде - это расширение GCC.

Раздел руководства GCC, описывающий эту функцию, называется "Выражения и объявления в выражениях":

Составной оператор, заключенный в круглые скобки, может отображаться как выражение в GNU C.

Позже он говорит:

Любые временные числа, созданные в выражении оператора в выражении оператора, будут уничтожены на конец заявлений. Это делает выражения выражения внутри макросов слегка отличается от вызовов функций.

Итак, выражение "выражение" похоже на имя, используемое в документации.