Ответ 1
Он называется "braced-group in expression".
Это не разрешено ANSI/ISO C или С++, но gcc поддерживает его.
Просматривая источники ядра Linux, я нашел часть кода, где блок операторов, окруженных скобками, рассматривается как выражение a la lisp (или ML), то есть выражение, значение которого является значением последнего оператора.
Например:
int a = ({
int i;
int t = 1;
for (i = 2; i<5; i++) {
t*=i;
}
t;
});
Я рассматривал грамматику ANSI C
Он называется "braced-group in expression".
Это не разрешено ANSI/ISO C или С++, но gcc поддерживает его.
Это не действует C это gcc
расширение называется выражение выражения, вы можете найти полный список расширений C здесь. Это на самом деле одно из многих расширений gcc, используемых в ядре Linux, и похоже, что clang тоже поддерживает это, и хотя он явно не указан в документе.
Как вы заметили, последнее выражение служит значением выражения, в документе говорится (внимание мое):
Последнее в составном выражении должно быть выражением, за которым следует точка с запятой; значение этого подвыражения служит значением всей конструкции. (Если вы используете какой-то другой оператор, последний в фигурных скобках, конструкция имеет тип void и, следовательно, фактически не имеет значения.)
Одним из основных преимуществ было бы создание безопасных макросов, которые позволяли бы избежать множественных оценок аргументов с побочными эффектами. В приведенном примере используется этот небезопасный макрос:
#define max(a,b) ((a) > (b) ? (a) : (b))
который дважды оценивает a
или b
и может быть переписан для устранения этой проблемы с использованием выражений оператора следующим образом:
#define maxint(a,b) \
({int _a = (a), _b = (b); _a > _b ? _a : _b; })
Обратите внимание, что необходимо явно использовать int
который может быть установлен с использованием другого расширения gcc
Typeof:
#define max(a,b) \
({ typeof (a) _a = (a), _b = (b); _a > _b ? _a : _b; })
Обратите внимание, что clang также поддерживает typeof.