Does not evaluating the expression to which sizeof is applied make it legal to dereference a null or invalid pointer inside sizeof in C++?

I believe this is currently underspecified in the standard, like many issues such as What is the value category of the operands of C++ operators when unspecified?. I don’t think it was intentional, like hvd points outs it is probably obvious to the committee.

In this specific case I think we have the evidence to show what the intention was. From GB 91 comment from the Rapperswil meeting which says:

It is mildly distasteful to dereference a null pointer as part of our specification, as we are playing on the edges of undefined behaviour. With the addition of the declval function template, already used in these same expressions, this is no longer necessary.

and suggested an alternate expression, it refers to this expression which is no longer in the standard but can be found in N3090:

noexcept(*(U*)0 = declval<U>())

The suggestion was rejected since this does not invoke undefined behavior since it is unevaluated:

There is no undefined behavior because the expression is an unevaluated operand. It’s not at all clear that the proposed change would be clearer.

This rationale applies to sizeof as well since it’s operands are unevaluated.

I say underspecified but I wonder if this is covered by section 4.1 [conv.lval] which says:

The value contained in the object indicated by the lvalue is the rvalue result. When an lvalue-to-rvalue conversion occurs
within the operand of sizeof (5.3.3) the value contained in the referenced object is not accessed, since that operator
does not evaluate its operand.

It says the value contained is not accessed, which if we follow the logic of issue 232 means there is no undefined behavior:

In other words, it is only the act of “fetching”, of lvalue-to-rvalue conversion, that triggers the ill-formed or undefined behavior

This is somewhat speculative since the issue is not settled yet.

Leave a Comment