Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++0x: noexcept(ndebug) for testing?

I read about concern that the overly use of noexcept may hinder a testable library.

Consider:

T& vector::front() noexcept {
    assert(!empty());         // <- this may throw in some test-frameworks
    return data[0];
}

With the annotation with noexcept the compiler may optimize exception-code out, which would/could prevent proper handling of assert() (or whichever function the author wants to use here for his tests).

Therefore, I wonder, if it is feasible in a library to never use an unconditional noexcept but to always "link" it with a am-I-in-a-test-condition. Like this:

#ifdef NDEBUG    // asserts disabled
static constexpr bool ndebug = true;
#else            // asserts enabled
static constexpr bool ndebug = false;
#end

T& vector::front() noexcept(ndebug) {
    assert(!empty());
    return data[0];
}

and then maybe add it as a macro (although, I hate that):

#define NOEXCEPT noexcept(ndebug)

T& vector::front() NOEXCEPT {
    assert(!empty());
    return data[0];
}

What do you think? Does this make any sense at all? Or is it not feasible? Or does it not solve the problem? Or is there no problem at all? :-)

like image 431
towi Avatar asked Sep 10 '11 13:09

towi


People also ask

What is the purpose of Noexcept in C++?

The noexcept operator performs a compile-time check that returns true if an expression is declared to not throw any exceptions. It can be used within a function template's noexcept specifier to declare that the function will throw exceptions for some types but not others.

Why is Noexcept important?

The noexcept keyword has another purpose: You can use it as an operator in an expression, and it evaluates to true if the evaluation of the argument would be considered non-throwing by the compiler. Like sizeof , the argument itself is not evaluated.

Can be declared Noexcept?

Function can be declared 'noexcept'. If code isn't supposed to cause any exceptions, it should be marked by using the noexcept specifier. This annotation helps to simplify error handling on the client code side, and enables the compiler to do more optimizations.

Why should move operations be labeled Noexcept when possible?

noexcept is to provide information for compiler, allow it to generate optimized code against non-throwing functions.


1 Answers

If you cannot prove that a function will not emit an exception then you should not tag it with noexcept. It's that simple.

That said, noexcept(ndebug) seems reasonable to me. I see no reason to hide it behind a macro. Template functions often have verbose noexcept conditions.

If the function within the asset can throw during test modes then your program can spontaneously std::terminate during test mode. (It's a lot like an implicit assert actually.)

The only downside I can see is that if this happens you won't get a line number and hint message. That, and the compiler ought to warn you if you call a noexcept(false) function from a noexcept(true) one, so you might get some noise.

like image 184
spraff Avatar answered Oct 03 '22 15:10

spraff