On Apr 20, 2014, at 13:19, Mark Rowe <mr...@apple.com> wrote: > > On Apr 20, 2014, at 13:08, Filip Pizlo <fpi...@apple.com> wrote: > >> >> >> On Apr 20, 2014, at 12:56 PM, Mark Rowe <mr...@apple.com> wrote: >> >>> >>> On Apr 19, 2014, at 13:09, Filip Pizlo <fpi...@apple.com> wrote: >>> >>>> Hey everyone, >>>> >>>> When guarding code with macros that are always defined, such as >>>> ASSERT_DISABLED (it's always either 0 or 1), we have a choice between: >>>> >>>> if (!ASSERT_DISABLED) { >>>> // do things >>>> } >>>> >>>> and: >>>> >>>> #if !ASSERT_DISABLED >>>> // do things >>>> #endif >>>> >>>> I'd like to propose that anytime the normal if would be semantically >>>> equivalent to the preprocessor #if, the normal if should be used. >>>> >>>> We don't lose any compiler optimization, since even at -O0, the compiler >>>> will constant fold the normal if. We do gain a lot of clarity, since the >>>> control flow of normal if statements is subject to proper indentation. >>>> >>>> The "semantically equivalent" requirement still allows for #if to be used >>>> for thinngs like: >>>> >>>> - Guarding the placement of fields in a class. >>>> - Guarding the definitions of other macros (in the case of >>>> ASSERT_DISABLED, we define ASSERT in different ways guarded by #if's) >>>> - Guarding the definition/declaration/inclusion of entire functions, >>>> classes, and other top-level constructs. >>>> >>>> Thoughts? >>> >>> It’d be one thing if we could adopt this approach everywhere, but as you >>> note there are numerous situations in which it won’t compile. What’s worse >>> is that there are situations in which it’ll silently give unintended >>> behavior. >> >> Can you give an example of this? > > Won’t compile: > > if (!MAYBE_DEFINED) { > … > } > > if (SOMETHING) { > void doSomething() { } > } > > if (SOMETHING) { > #include “Something.h" > }
It’s also not possible to determine from context alone whether #if or if should be used. When #if is used to remove members or functions you’re then forced to use #if, rather than if, around all uses of those members or functions since the alternative won’t compile. An example lifted from Vector.h: #if !ASSERT_DISABLED template<typename T> struct ValueCheck<Vector<T>> { typedef Vector<T> TraitType; static void checkConsistency(const Vector<T>& v) { v.checkConsistency(); } }; #endif template<typename T, size_t inlineCapacity, typename OverflowHandler> inline void Vector<T, inlineCapacity, OverflowHandler>::checkConsistency() { if (!ASSERT_DISABLED) { for (size_t i = 0; i < size(); ++i) ValueCheck<T>::checkConsistency(at(i)); } } This won’t compile with assertions disabled because ValueCheck::checkConsistency doesn’t exist. - Mark
_______________________________________________ webkit-dev mailing list webkit-dev@lists.webkit.org https://lists.webkit.org/mailman/listinfo/webkit-dev