templates to generate compiler diagnostics

N

Niklas Norrthon

I just want to share a technique I discovered when playing
around with templates. It is a simple idea, so I doubt I
am first, perhaps it's even used in the standard library
implementations, and the boost library.

Anyway, the idea is to use templates as a compile time
assert, letting the compiler fail, with a reasonable
diagnostics if some condition isn't fulfilled.

For example, consider a template function that shifts
variables of the template argument type left and right,
then it would be nice to assure that the template
argument time isn't signed, since right shifting isn't
well defined on negative values:

template <typename IntType>
IntType func(IntType x)
{
/* do operations on x */
x >>= 1; /* what if x < 0? */
return x;
}

My solution is this:

#include "compile_assert.h"
#include <limits>

template <typename IntType>
IntType func(IntType x)
{
compile_assert< ! std::numeric_limits<IntType>::is_signed > ();

/* do operations on x */
x >>= 1; /* what if x < 0? */
return x;
}

The code result in a compiler diagnostic pointing to the compile_assert
line if the function is called with a signed type argument.

Here is the definition of compile_assert:

#ifndef H_COMPILE_ASSERT
#define H_COMPILE_ASSERT

namespace {
template <bool is_ok> struct compile_assert_t;
template <> struct compile_assert_t<true> { };
}

template <bool is_ok> void compile_assert()
{
compile_assert_t<is_ok>();
}

#endif

No question just wanted to share, comments are welcome.

/Niklas Norrthon
 
M

mlimber

Niklas said:
I just want to share a technique I discovered when playing
around with templates. It is a simple idea, so I doubt I
am first, perhaps it's even used in the standard library
implementations, and the boost library.

Anyway, the idea is to use templates as a compile time
assert, letting the compiler fail, with a reasonable
diagnostics if some condition isn't fulfilled.

For example, consider a template function that shifts
variables of the template argument type left and right,
then it would be nice to assure that the template
argument time isn't signed, since right shifting isn't
well defined on negative values:

template <typename IntType>
IntType func(IntType x)
{
/* do operations on x */
x >>= 1; /* what if x < 0? */
return x;
}

My solution is this:

#include "compile_assert.h"
#include <limits>

template <typename IntType>
IntType func(IntType x)
{
compile_assert< ! std::numeric_limits<IntType>::is_signed > ();

/* do operations on x */
x >>= 1; /* what if x < 0? */
return x;
}

The code result in a compiler diagnostic pointing to the compile_assert
line if the function is called with a signed type argument.

Here is the definition of compile_assert:

#ifndef H_COMPILE_ASSERT
#define H_COMPILE_ASSERT

namespace {
template <bool is_ok> struct compile_assert_t;
template <> struct compile_assert_t<true> { };
}

template <bool is_ok> void compile_assert()
{
compile_assert_t<is_ok>();
}

#endif

No question just wanted to share, comments are welcome.

/Niklas Norrthon

Your assert is akin to BOOST_STATIC_ASSERT
(http://www.boost.org/doc/html/boost_staticassert.html) and Loki's
STATIC_CHECK, which are used to great avail in those libraries and
elsewhere. You could also use typetraits from either of those libraries
to check the signedness of a type without using <limits>.

Cheers! --M
 
V

Victor Bazarov

mlimber said:
[..] You could also use typetraits from either of those libraries
to check the signedness of a type without using <limits>.

Of course one could also use some third-party library to do things that
are already covered by the Standard Library. But WHY?
 
M

mlimber

Victor said:
mlimber said:
[..] You could also use typetraits from either of those libraries
to check the signedness of a type without using <limits>.

Of course one could also use some third-party library to do things that
are already covered by the Standard Library. But WHY?

Fair enough. I would note, however, that Boost.Typetraits are included
in TR1
(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1745.pdf) and
may someday be part of the standard, thus providing two standard ways
to accomplish the same thing.

Cheers! --M
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,681
Members
48,796
Latest member
Greg L.

Latest Threads

Top