R3DL
R3DL

Reputation: 229

Compile-time assert using templates in c++

I was reading code from the cpp-btree library of google (https://code.google.com/p/cpp-btree/) and I came accross that compile-time assert mechanism.

// A compile-time assertion.
template <bool>
  struct CompileAssert {
};

#define COMPILE_ASSERT(expr, msg) \
  typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1]

So I understand more or less what it does, if expr is evaluated to false by the compiler it will declare a new type msg that will be a CompileAssert < false > array of size -1 which will trigger a compilation error.

What I don't get is the bool(expr) part, what is this exactly? Some kind of call to the copy constructor of the class bool? (but it's a builtin type so I'm confused) I though this would be a mechanism to raise a compilation error when expr is not a boolean but actually I managed to compile a short program whit that line

COMPILE_ASSERT("trash",error_compilation_assert);

It compiles just fine with gcc 3.4

So can anyone explain the bool(expr) part of the mechanism?

Upvotes: 2

Views: 661

Answers (5)

It's a type conversion. There are 3 main types of type conversions in C++:

  • Cast notation (C-style cast): (bool) expr

  • Functional notation (constructor-style cast): bool(expr)

  • Cast operators (C++-style cast); static_cast<bool>(expr)

Cast notation and functional notation are semantically equivalent (i.e. they both perform the strongest possible conversion, the C-cast), but the scope & precedence of the functional notation is clearer.

It is generally advised not to use them in C++ code and use the specific cast operators (const_cast, static_cast etc.) instead.

So in your code, it's just a way of forcing the value to type bool and enclosing it in parentheses at the same time, so that no operator priority issues arise.

Upvotes: 4

Neil Kirk
Neil Kirk

Reputation: 21763

The first parameter should be some kind of expression, such as a == b. Using a string literal here is useless.

bool(expr) is a function-style cast which converts the expression to a bool. Lots of things convert implicitly to bool, but I guess they wanted an explicit cast to make sure the result is a bool.

If you convert a pointer to a bool, it evaluates to false if it is a NULL pointer, or true otherwise. Your string literal "Trash" decays into a const char * to the first character. As this is not a null pointer, the expression evaluates to true.

Upvotes: 1

Nikos C.
Nikos C.

Reputation: 51832

In C++, you can instantiate built-in types with ctor syntax:

bool b1 = bool(true);
bool b2 = bool(b1);

The difference to:

bool b2 = b1;

is that the latter does an implicit conversion to bool. When such an implicit conversion isn't allowed (as in the template typedef), then bool(b1) makes it explicit by creating a temporary bool from b1 and the temporary doesn't have to be converted anymore; it's an actual bool type.

Upvotes: 0

anonymous
anonymous

Reputation: 1968

bool(expr) tries to convert expr to bool either implicitly or using any user defined conversion operator.

Upvotes: 0

Oswald
Oswald

Reputation: 31637

bool(expr) casts expr into a bool.

Upvotes: 3

Related Questions