C2x, 6.5.3.4 The sizeof and _Alignof operators, Semantics, 2 (emphasis added):
If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.
C2x, 6.7.6.2 Array declarators, Semantics, 5 (emphasis added):
Where a size expression is part of the operand of an
_Alignof
operator, that expression is not evaluated.
Consider this code:
int f(void)
{
return _Alignof( int(*)[ f() ] );
}
Question: shall f()
be called?
Per 6.5.3.4 the type of the operand is a variable length array type => the operand is evaluated.
Per 6.7.6.2 the size expression is part of the operand of an _Alignof
operator => that expression is not evaluated.
Is there a contradiction in the standard?
If no, then does it mean that 6.7.6.2 have higher priority than 6.5.3.4?
The standard was overlooked.
There is no contradiction.
To clarify:
C11, 6.5.3.4 The sizeof and _Alignof operators, Semantics, 3 (emphasis added):
The
_Alignof
operator yields the alignment requirement of its operand type. The operand is not evaluated and the result is an integer constant.
It means that in
_Alignof( int(*)[ f() ] )
the
int(*)[ f() ]
is not evaluated.
Hence, the f()
is not called.
Extra: ICC incorrectly produces an error:
int f(void);
int s = _Alignof( int(*)[ f() ] );
$ icc -std=c11 -pedantic -Wall -Wextra -c
error: function call is not allowed in a constant expression
Here the function call is allowed because such funtion call is
contained within a subexpression that is not evaluated