Search code examples
clanguage-lawyerevaluationalignof

_Alignof with operand of variable length array type: is there a contradiction in the standard?


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?


Solution

  • 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