Насколько я понимаю, последнее также будет ложным, если Foo undefined? Где я могу прочитать об этом?
Ответ 1
Если Foo - undefined, то последний переведёт на
#if 0 - 0 == 0
который является истинным, а не ложным. Помните, что под #if все идентификаторы undefined заменяются литералом 0 (как только все операторы defined() оцениваются, конечно). Это относится даже к токенам предварительной обработки, которые соответствуют языковым ключевым словам. В языке C все ключевые слова заменяются на 0 в этом контексте. В С++ ключевые слова true и false освобождаются от замены, тогда как все остальные ключевые слова заменяются.
(BTW, это означает, что в C true будет тихо заменен на 0, если <stdbool.h> не включен, а с помощью 1, если включен <stdbool.h>.)
Между тем
#if defined(Foo) && Foo == 0
неверно, если Foo - undefined. Итак, вот ваша разница.
Документация Qt действительно показывает, что первая такая же, как и последняя. Я не знаю, почему они это делают, поскольку они, безусловно, не эквивалентны. Это, по-видимому, ошибка в документах Qt.
Ответ 2
Разница между Foo == 0 и Foo - 0 == 0 заключается в том, что в первом Foo должен быть определен со значением:
#define Foo 0
и не может быть:
#define Foo // Foo == 0 would give an error, cannot evaluate Foo
В то время как в случае Foo - 0 == 0, Foo может быть определен без значения
Итак:
#if defined(Foo) && Foo == 0
Определяется Foo и имеет значение (в данном случае 0).
и
#if Foo - 0 == 0
Значения Foo либо определены с 0, либо определены без значения, но поскольку он не имеет определенного (Foo), как в первом случае, Foo undefined также применим.