Any reason to use a run-time assert instead of compile-time assert?
Asked Answered
D

2

6

While reviewing Visual C++ codebase I found a following strange thing. A run-time assert (which is check the condition and throw an exception if the condition is violated) was used in a case when the condition could be evaluated at compile time:

assert( sizeof( SomeType ) == sizeof( SomeOtherType ) );

clearly the compiler will evaluate the condition and replace the code that will effectively be either

assert( true );

which does nothing or

assert( false );

which throws an exception every time control passes through that line.

IMO a compile-time assert should have be used instead for the following reasons:

  • it would expose the condition violation earlier - at compile time - and
  • it would let cleaner (thus faster and smaller) machine code be emitted

Looks like a compile-time assert is the only right thing. Is there any possible reason to prefer a run-time assert here?

Degree answered 7/9, 2010 at 13:59 Comment(4)
assert usually does not throw an exception but rather aborts the program.Steels
As of yet, there is no standard compile-time assert. That fact is pretty important, especially in older code bases.Marcellemarcellina
Specifically, VC6 has all sorts of special case code throughout the Boost libraries. If your code is now, or has ever been, compiled by VC6 (and one can probably assume this is true for much of MSs own source), at the very least BOOST_STATIC_ASSERT is probably right out of the question.Marcellemarcellina
Most asserts() compile to null operations in release. They are only active in Debug (ie Test code).Bakemeier
W
17

There's no reason to prefer a run-time assert here. You should prefer compile-time errors over run-time errors so there's never a reason, given the option between the two, to choose a run-time assert.

However, if a static assert isn't an option (doesn't know the concept of a static assert, doesn't know how to make one and doesn't have one available, or knows how to make one but doesn't have the time to), a run-time assert is the next best thing.

With C++0x, the built-in static_assert feature should end all reason to use a run-time assert where a compile-time assert would work.

Whittemore answered 7/9, 2010 at 14:5 Comment(0)
D
4

We can't tell without context. In template code, some branches might be unreachable for some instantiations. A compile-time assert would be inappropriate, as that renders the entire function illformed. An assert(<type-dependent expression>) does not.

E.g.

template <typename T> void foo(T t)
{
  if (t < 0) {
    assert(std::numeric_limits<T>::min() < 0);
    T u = t - std::numeric_limits<T>::min();
  }
}

The assert cannot be converted to a static assert, even though the run-time assert never fails.

Deirdra answered 7/9, 2010 at 14:27 Comment(5)
Why can't it be made a static_assert?Whittemore
assert(std::numeric_limits<T>::min < 0); always fails, regardless of T.Danley
@usta: are you commenting on the lack of a function call? @MSalters: I think you wanted min()Marcellemarcellina
@Dennis Zickefoose Yes, I'm commenting on absence of (). With it added, that assert still can't be turned into static assert because std::numeric_limits<T>::min() is not (yet) a compile-time expression.Danley
Fixed missing (). @Gman: because a static_assert would stop foo<unsigned int> from compiling.Deirdra

© 2022 - 2024 — McMap. All rights reserved.