Date
2017-08-18.19:58:35
Message id
9447

Content

The C standard says that the expression in an assert must have a scalar type, and implies (or at least allows) that the condition is tested by comparison to zero. C++ says that the expression is a constant subexpression if it can be contextually converted to bool. Those ways to test the condition are not equivalent.

It's possible to have expressions that meet the C++ requirements for a constant subexpression, but fail to meet the C requirements, and so don't compile.

#include <stdlib.h>

// A toy implementation of assert:
#define assert(E) (void)(((E) != 0) || (abort(), 0))

struct X {
  constexpr explicit operator bool() const { return true; }
};

constexpr bool f(const X& x) {
  assert(x);
  return true;
}

C++ says that assert(x) is a constant subexpression, but as it doesn't have scalar type it's not even a valid expression.

I think either [cassert.syn] or [assertions.assert] should repeat the requirement from C that E has scalar type, either normatively or in a note. We should also consider whether "contextually converted to bool" is the right condition, or if we should use comparison to zero instead.