5
votes

I've recently started reading Modern C++ Design by Andrei Alexandrescu. After reading Compile-Time Assertions, I tried the following code:

template<bool> struct CompileTimeChecker
{
    CompileTimeChecker(...){};
};
template<> struct CompileTimeChecker<false>{};

#define STATIC_CHECK(expr, msg) \
{\
    class ERROR_##msg{}; \
    (void)sizeof(CompileTimeChecker<(expr)!=0>((ERROR_##msg())));   /*Line 1*/ }


int main()
{
    STATIC_CHECK(sizeof(char)>sizeof(int),TypeTooNarrow); /*Line 2*/

    STATIC_CHECK(sizeof(char)<sizeof(int),TypeTooNarrow); /*Line 3*/
}

The code should not compile due to Line 2, but it compiles fine. If I change the Line 1 to

(void)(CompileTimeChecker<(expr)!=0>((ERROR_##msg())));   /*Line 1*/ }

or

new CompileTimeChecker<(expr)!=0>((ERROR_##msg()));   /* Line 1*/ }

it works as expected. I don't get it.

2
Close the other one as duplicate. Let this one be open. - Saurabh Manchanda
@Paul R : I think @Saurabh posted the same question twice (by mistake I think), the other one has already been closed as a duplicate to this one and now you are closing this considering this one as the dupe of other one. - Prasoon Saurav
@Prasoon: when I voted to close this duplicate both were still open - normally the newer duplicate is closed, but I guess it doesn't matter so long as only one remains - Paul R

2 Answers

0
votes

Since C++11 it's preferable to use static_assert rather than this technique. A lot of what is described in Modern C++ Design has now been replaced by standard language or library features. It's (probably) still worth reading though.