Spec-Zone.ru › GCC 5 CPP

3.10.2 Проблемы с приоритетом операторов

Вы, возможно, заметили, что во многих примерах определения макросов, показанных выше, у каждого имени аргумента макроса есть скобки. Кроме того, обычно вокруг всего определения макроса находится еще одна пара скобок. Вот почему лучше писать макросы именно таким образом.

Предположим, вы определили макрос следующим образом:

#define ceil_div(x, y) (x + y - 1) / y

назначение которого — деление с округлением вверх. (Одно из применений этой операции — вычисление количества int объектов, необходимых для хранения определенного количества char объектов.) Затем предположим, что он используется следующим образом:

a = ceil_div (b & c, sizeof (int));
     → a = (b & c + sizeof (int) - 1) / sizeof (int);

Это не делает того, что ожидается. Правила приоритета операторов языка C делают его эквивалентным этому:

a = (b & (c + sizeof (int) - 1)) / sizeof (int);

То, что мы хотим, — это следующее:

a = ((b & c) + sizeof (int) - 1)) / sizeof (int);

Определение макроса как

#define ceil_div(x, y) ((x) + (y) - 1) / (y)

обеспечивает желаемый результат.

Нежелательное группирование может возникнуть и другим способом. Рассмотрим sizeof ceil_div(1, 2). Это выглядит как выражение языка C, которое вычислило бы размер типа ceil_div (1, 2), но на самом деле это означает нечто совершенно другое. Вот к чему это приводит:

sizeof ((1) + (2) - 1) / (2)

Это возьмёт размер целого числа и разделит его на два. Правила приоритета поместили деление за пределы sizeof, тогда как оно должно было стоять внутри.

Скобки вокруг всего определения макроса предотвращают такие проблемы. Таким образом, рекомендуется определять ceil_div следующим образом:

#define ceil_div(x, y) (((x) + (y) - 1) / (y))

Далее: Поглощение точки с запятой, Предыдущее: Вложенность, Наверх: Недостатки макросов [Оглавление][Индекс]

© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-5.5.0/cpp/Operator-Precedence-Problems.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API