Как это называется, когда блок возвращает значение? - PullRequest
7 голосов
/ 01 декабря 2011

Я недавно сталкивался с этим кодом, который не выглядит законным для меня (но gcc его компилирует).Я не столько против конструкции, сколько для ее имени:

#define MAX(a,b) \
({ \
    typeof(a) _a = (a); \
    typeof(b) _b = (b); \
    (_a > _b) ? (_a) : (_b); \
})

По-видимому, значение последнего оператора возвращается как «значение» выражения, ограниченного пространством имен.

Редактировать: Спасибо за ответы, ребята.Оказывается, это расширение простого C, называемого выражениями операторов.

Ответы [ 5 ]

12 голосов
/ 01 декабря 2011

Это не пространство имен , это макрос , который возвращает максимум два значения.
\ в конце операторов используется для добавления нескольких операторови создайте многострочный макрос.

Код не является стандартным C ++, но компилируется в gcc, поскольку поддерживается как расширение компилятора gcc .

Хорошее чтение:

Выражения операторов:
Составной оператор - это последовательность операторов, заключенная в фигурные скобки.В GNU C составной оператор в скобках может отображаться в виде выражения в так называемом Statement expression.

         .--------------.
         V              |
>>-(--{----statement--;-+--}--)--------------------------------><

Значением выражения оператора является значение последнего простого выражения, которое появляется вВся конструкция.Если последний оператор не является выражением, то конструкция имеет тип void и не имеет значения.

Примечание: Этот отрывок взят из документации IBM XL C / C ++ v7.0.

7 голосов
/ 01 декабря 2011

Это называется операторным выражением и является нестандартным расширением GCC.Он позволяет вам использовать составной оператор в качестве выражения со значением, заданным последним выражением в составном операторе.

Используется здесь, чтобы избежать проблемы, когда функционально-подобные макросы могут оценивать свои аргументы несколько разнепредсказуемое поведение, если эти оценки имеют побочные эффекты.Макрос тщательно написан для точной оценки a и b.

В C ++ вам никогда не нужно делать ничего подобного - используйте вместо этого шаблоны функций:

template <typename T> T max(T const & a, T const & b) {
    return a > b ? a : b;
}
2 голосов
/ 01 декабря 2011

Операторы {} в этом контексте являются «анонимным оператором области видимости» (он же «лексическое вложение», «форма» и другими различными вещами. Они используются, в некотором роде как пространство имен, для ограничения область действия _a и _b внутри фигурных скобок, чтобы они не конфликтовали с другими переменными, которые могут иметься с теми же именами. «auto» переменные, определенные в {фигурных скобках}, будут «уничтожены» после достижения закрывающей фигурной скобки, или для нелокальной передачи, например «return» или «longjmp». Однако вы не можете надежно использовать «goto» для их передачи.

Вы, вероятно, привыкли видеть их только после операторов "if", "do", "while" и "for", но думаете, что это способ, как правило, "объединить" несколько операторов в один "слот, «так же, как вы выполняете несколько операторов в качестве предложения« then »или« else »в выражении« if »(где, оставляя скобки, у вас есть только один оператор« slot »)

Как указал Майк Сеймур, операция ({}) является нестандартным расширением GCC, которое возвращает значение последнего элемента, оцененного в нем. Это очень похоже на общий оператор области видимости, за исключением встроенного возврата в конце.

2 голосов
/ 01 декабря 2011

Прежде всего, это не Стандарт C ++, потому что typeof является расширением C ++ от GCC.В коде используется другое расширение, которое называется расширением Statement.

Скомпилируйте ваш код с параметром -pedantic, оно не скомпилируется.

Что касается вопроса, это не пространство имен.Это просто макрос, который дает вам максимум два значения.

1 голос
/ 01 декабря 2011

Это макрос, как и любой другой #DEFINE. По сути, компилятор заменяет MAX (a, b) определенным в нем кодом. Это вернет максимальное значение.

...