Почему столько круглых скобок в макросе, за которым СЛЕДУЮТ?

Функции Windows SDK СЛЕДОВАЛИ за макросом:

#define SUCCEEDED(hr) (((HRESULT)(hr)) >= 0)
-----------------------^-------------^-----

ясно как с другими макросами существуют круглые скобки для обеспечения правильной интерпретации намерения компилятором.

То, что я не получаю, - то, почему существуют круглые скобки вокруг (HRESULT)(hr) (Я отметил их с ^ символ). hr заключается в скобки так, чтобы некоторая сложная конструкция могла быть там, HRESULT заключается в скобки для формирования броска C-стиля, затем целое >= конструкция заключается в скобки также, итак, почему дополнительная пара круглых скобок вокруг (HRESULT)(hr)?

6
задан Brian Tompsett - 汤莱恩 25 February 2016 в 18:51
поделиться

8 ответов

Стандарт C ставит приведение с более высоким приоритетом, чем сравнение, поэтому скобки не требуются для компилятора.

Тем не менее, люди читают определение макроса, и их добавление делает приоритет явным, так что для людей, читающих его, очевидно, что это результат сравнения ((HRESULT) hr) с нулем, а не приведение результата сравнение, не задумываясь о приоритете.

8
ответ дан 8 December 2019 в 04:28
поделиться

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

Чтобы уточнить, я имею в виду только круглые скобки вокруг выражения приведения, отмеченные в вопросе. Остальные необходимы (если макрос не предназначен только для C ++, а не для C; в этом случае вы можете изменить (HRESULT) (hr) на HRESULT (hr) ).

5
ответ дан 8 December 2019 в 04:28
поделиться

Краткий ответ: кто знает, о чем думали разработчики MS. Однако круглые скобки вокруг hr, очевидно, необходимы, поскольку hr может быть выражением, состоящим из более чем одного операнда. Скобки вокруг ((HRESULT) (hr)), насколько я понимаю, не нужны. Вероятно, это было сделано из предупредительной привычки: при работе с препроцессором лучше иметь слишком много скобок, чем слишком мало.

3
ответ дан 8 December 2019 в 04:28
поделиться

Это для устранения недостатков макросов - они всего лишь замена текста!

представьте себе следующий макрос

#define DOUBLE(x) x*2

int v = DOUBLE(1+1); // == 1+1*2 == 3. Did you expect 4?

Итак, практические правила для макросов следующие:

  • используйте их только в том случае, если нет другого способа решить вашу проблему
  • заключите каждый параметр в скобки (чтобы избежать вышеуказанной проблемы)
  • заключить все выражение в скобки (чтобы избежать других подобных проблем)
  • сделать так, чтобы каждый параметр появлялся только один раз (чтобы избежать проблем с побочными эффектами)

Таким образом, лучшим макросом будет:

#define DOUBLE ( x) ((x) * 2)

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


Итак, мы можем критиковать два момента:

Q: почему это макрос, а не встроенная функция?
A: Обратная совместимость. В C нет встроенных функций (или, по крайней мере, их не было), использование функций для, вероятно, тысяч таких объявлений привело бы к остановке большинства компиляторов того времени.

Q: Действительно ли скобки необходимы для этого конкретного макроса? A: Не знаю. Мне, вероятно, потребовалось бы полчаса или больше, чтобы формально доказать (или опровергнуть), что нет разумного параметра и «вызывающей» среды, в которой это имеет непредвиденные последствия. Я лучше буду следовать разумным рекомендациям, упомянутым выше, и продолжу кодирование.

3
ответ дан 8 December 2019 в 04:28
поделиться

Автор просто глуп. Все лишние круглые скобки (вокруг приведенного текста) затрудняют визуальный синтаксический анализ. Любой, кто думает, что сравнение может иметь более высокий приоритет, чем приведение, должен изучить основы языка перед кодированием ... не говоря уже о том, чтобы просто получить некоторый здравый смысл.

3
ответ дан 8 December 2019 в 04:28
поделиться

Раскосы обеспечивают правильное расположение элементов. Вы не хотите, чтобы компилятор выполнял следующие действия:

  1. (hr)> = 0

  2. преобразовать результат 1. в HRESULT .

Вместо этого вы хотите преобразовать только выражение (hr) в HRESULT , а затем сравнить его с 0 .

2
ответ дан 8 December 2019 в 04:28
поделиться

Обеспечивает преобразование hr в HRESULT перед сравнением вместо HRESULT (hr> = 0).

1
ответ дан 8 December 2019 в 04:28
поделиться

Чтобы убедиться, что выражение, которое расширяется от (hr), приводится к HRESULT, а THEN по сравнению с 0.

0
ответ дан 8 December 2019 в 04:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: