24
    #define TYPE_CHECK(T, S)                                     \
    while (false) {                                              \
      *(static_cast<T* volatile*>(0)) = static_cast<S*>(0);      \
    }

I am reading Google v8's code and found the above macro for type check.

However, I do not understand why it works. while(false) never get executed, right? Can someone explain those lines? Thanks

Byron Whitlock
  • 52,691
  • 28
  • 123
  • 168
Jexcy
  • 594
  • 4
  • 15
  • 3
    It is a compile time check of two types which assignes the content of one null pointer to another. The compiler would detect incompatibility of types (and stop compilation). The code would **NOT** be executed (thanks to) due to the false value in the condition. – rubber boots Mar 08 '11 at 19:20
  • Really neat.. this is going to my trunk right now! – JoeSlav Mar 08 '11 at 19:25
  • is there any reason to use 'while' instead of 'if'? – Jexcy Mar 08 '11 at 19:26
  • 2
    `while` is used since `if` would allow `else` afterwards, which might happen accidentially ... – Alexander Gessler Mar 08 '11 at 19:28
  • if cannot be used because of its paring with nearest else. With if you could not do e.g. if (xxx) TYPE_CHECK(T,S) else SOMETHING_ELSE(T,S) – Suma Mar 08 '11 at 19:28
  • IMO it's ugly. Better use a real function template for this and don't pollute the global name space. Using textual replacement has drawbacks and hidden pitfalls. Consider how you cannot do `TYPE_CHECK(int[1], int[1]);`. Previously I thought that it would fail with `TYPE_CHECK(::type, foo)` (producing the alternative token <:), but I'm wrong. `static_cast`, when expanding `T`, doesn't produce such an alternative token out of the `<` and the start of expanded `T`. I don't like nor know macros, obviously :) – Johannes Schaub - litb Mar 09 '11 at 12:54
  • I think we should rename this question to be able to search for it. Something like "static_cast in while(false)". Any objections? – Kiril Kirov Aug 08 '11 at 09:36
  • why assignment is not removed by the compiler due to the optimization ? `while (false)` can be detected as a 'will never execute' – cprogrammer Aug 08 '11 at 09:43
  • 1
    @cprogrammer: The compiler probably won't emit any code, but it still has to check the source for errors. You can't write `if (false) some_function_that_does_not_exist();` either. – Steve Jessop Aug 08 '11 at 10:28

2 Answers2

12

Quite a fancy hack - the purpose of the macro seems to be to check if the type S is assignable to (i.e., is a subclass of) the type T. If it is not, the pointer cast from S* to T* will produce a compiler error. The while (false) prevents the code from actually having any other effect.

Aasmund Eldhuset
  • 37,289
  • 4
  • 68
  • 81
7

Yes, but the compiler still performs syntax & semantic checks on the loop contents. So if something is wrong (i.e. the implicit type conversion from S* to T* is illegal, which happens if T is neither S nor a base class of S), compilation fails. Otherwise, the quality of the resulting machine code is not affected since the optimizer will detect the nonreachable code and remove it silently.

Alexander Gessler
  • 45,603
  • 7
  • 82
  • 122
  • 2
    The casts are always legal. The code is testing for existence of a standard conversion from `S*` to `T*`. (`T` may be a base class of `S`.) – aschepler Mar 08 '11 at 19:24