Функции Windows SDK СЛЕДОВАЛИ за макросом:
#define SUCCEEDED(hr) (((HRESULT)(hr)) >= 0)
-----------------------^-------------^-----
ясно как с другими макросами существуют круглые скобки для обеспечения правильной интерпретации намерения компилятором.
То, что я не получаю, - то, почему существуют круглые скобки вокруг (HRESULT)(hr)
(Я отметил их с ^
символ). hr
заключается в скобки так, чтобы некоторая сложная конструкция могла быть там, HRESULT
заключается в скобки для формирования броска C-стиля, затем целое >=
конструкция заключается в скобки также, итак, почему дополнительная пара круглых скобок вокруг (HRESULT)(hr)
?
Стандарт C ставит приведение с более высоким приоритетом, чем сравнение, поэтому скобки не требуются для компилятора.
Тем не менее, люди читают определение макроса, и их добавление делает приоритет явным, так что для людей, читающих его, очевидно, что это результат сравнения ((HRESULT) hr) с нулем, а не приведение результата сравнение, не задумываясь о приоритете.
Дополнительные круглые скобки не меняют значения, но они явно определяют приоритет. Без них читателю, не знающему всех правил приоритета, пришлось бы понять, что означает это выражение.
Чтобы уточнить, я имею в виду только круглые скобки вокруг выражения приведения, отмеченные в вопросе. Остальные необходимы (если макрос не предназначен только для C ++, а не для C; в этом случае вы можете изменить (HRESULT) (hr)
на HRESULT (hr)
).
Краткий ответ: кто знает, о чем думали разработчики MS. Однако круглые скобки вокруг hr, очевидно, необходимы, поскольку hr может быть выражением, состоящим из более чем одного операнда. Скобки вокруг ((HRESULT) (hr)), насколько я понимаю, не нужны. Вероятно, это было сделано из предупредительной привычки: при работе с препроцессором лучше иметь слишком много скобок, чем слишком мало.
Это для устранения недостатков макросов - они всего лишь замена текста!
представьте себе следующий макрос
#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: Не знаю. Мне, вероятно, потребовалось бы полчаса или больше, чтобы формально доказать (или опровергнуть), что нет разумного параметра и «вызывающей» среды, в которой это имеет непредвиденные последствия. Я лучше буду следовать разумным рекомендациям, упомянутым выше, и продолжу кодирование.
Автор просто глуп. Все лишние круглые скобки (вокруг приведенного текста) затрудняют визуальный синтаксический анализ. Любой, кто думает, что сравнение может иметь более высокий приоритет, чем приведение, должен изучить основы языка перед кодированием ... не говоря уже о том, чтобы просто получить некоторый здравый смысл.
Раскосы обеспечивают правильное расположение элементов. Вы не хотите, чтобы компилятор выполнял следующие действия:
(hr)> = 0
преобразовать результат 1. в HRESULT
.
Вместо этого вы хотите преобразовать только выражение (hr)
в HRESULT
, а затем сравнить его с 0
.
Обеспечивает преобразование hr в HRESULT перед сравнением вместо HRESULT (hr> = 0).
Чтобы убедиться, что выражение, которое расширяется от (hr), приводится к HRESULT, а THEN по сравнению с 0.