5

I have some generic code that needs to run an assertion over the result of a member function. This member function may be constexpr, or it may not be.

template<typename T>
void foo(T t) {
  assert(t.member_function() == 10);
}

Because t.member_function() might be a constant expression, I'm wondering if it's possible to be treated as a static_assert in such cases, but otherwise default to a normal assert. Is this possible?

Pubby
  • 51,882
  • 13
  • 139
  • 180

1 Answers1

2

This is a slightly crazy solution.

Uncomment the Const c; foo(c); line and you'll see that it won't compile. This is the compile-time assert.

It requires variable length arrays, and maybe other compiler specific stuff. I'm on g++-4.6.

The size of the array is either 0 or -1, depending on whether the member function returns 10. So if this can be computed at compile-time, then the compile realizes it's a non-variable length array, and that it has negative size. The negative size allows it to complain. Otherwise, it falls through to a conventional assert.

Please note: I'm getting some core dump with the Runtime version just after the runtime assertion fails. Maybe it doesn't like trying to free an array with negative size. Update: I'm getting core dumps with any assertion failure, even int main() {assert (1==2);}. Is this normal?

#include <iostream>
#include <cassert>
using namespace std;

struct Const {
        constexpr int member_function() { return 9; }
};
struct Runtime {
                  int member_function() { return 9; }
};

template<typename T>
void foo(T t) {
        if(0) {  // so it doesn't actually run any code to malloc/free the vla
            int z[(t.member_function()==10)-1]; // fails at compile-time if necessary
        }
        assert(t.member_function()==10);
}


int main() {
        //Const c; foo(c);
        Runtime r; foo(r);
}
Aaron McDaid
  • 26,501
  • 9
  • 66
  • 88
  • cool hack. although i'd have assumed the compiler be smart enough to directly ignore the if(0). lol like what if a constexpr of false were in an if statement. but i guess if might try compile what's inside with the constexpr creating that -1 size array, which fails the assertion. – Puddle Nov 23 '18 at 19:47