sizeof((type)) is a constraint violation?

Discussion in 'C Programming' started by Noob, Mar 7, 2012.

  1. Noob

    Noob Guest

    Hello,

    While debugging the output of a configure script, I came across
    the following program, which is refused by gcc.

    int main(void)
    {
    int res = sizeof((int));
    return res;
    }

    $ gcc -Wall -std=c89 -pedantic mini.c
    mini.c: In function 'main':
    mini.c:3:25: error: expected expression before ')' token

    Obviously, the compiler dislikes the double parenthesis
    around a type-name.

    Does this mean ((int)) cannot be takes as a unary-expression?
    However ((x)) or ((42)) are valid instances of unary-expression?

    http://www.cs.dartmouth.edu/~mckeeman/cs48/mxcom/doc/notation/c.html

    unary-expression
    postfix-expression
    ++ unary-expression
    -- unary-expression
    unary-operator cast-expression
    sizeof unary-expression
    sizeof ( type-name )

    Regards.
     
    Noob, Mar 7, 2012
    #1
    1. Advertisements

  2. Noob

    Nils M Holm Guest

    ((int)) is not a parenthesized primary expression, it is a
    parenthesized type cast, which is not a sentence that can
    be produced by the ANSI C grammar (as specified in The C
    Programming Language, 2nd Ed).

    ((int) x) would be a primary expression and would be accepted
    as an operand of 'sizeof'. More parens around the expression can
    be added to suit your taste.
    These, on the other hand, /are/ primary expressions.
     
    Nils M Holm, Mar 7, 2012
    #2
    1. Advertisements

  3. [...]

    Parentheses are heavily overloaded (used for different syntactic
    purposes) in C. They can be arbitrary nested in some cases, but not in
    others.

    For example, the parentheses in

    x * (y + z)

    create a parenthesized expression. Any expression or subexpression,
    even if it's already a parenthesized expression, can be enclosed in
    parentheses; the only effect is to make it a primary expression if it
    wasn't one already. So this:

    x * ((y + z))

    is also valid.

    Parentheses are also used to surround function arguments:

    func(x, y)

    These do *not* create a parenthesized expression. Surrounding them with
    a second set of parentheses doesn't create a two-level parenthesized
    expression. If you write:

    func((x, y))

    then that changes the meaning of the inner parentheses which now *do*
    form a parenthesized expression) and of the comma (which is now a comma
    operator, not a delimiter between function arguments).

    Yet another use of parentheses is in a sizeof operator applied to a type
    name:

    sizeof (int)

    These do not create a parenthesized expression, and they're *not*
    directly analagous to the parentheses in a function call. Instead,
    they're an inherent part of the syntax of a unary-expression:

    sizeof ( type-name )

    Just as with the parentheses in a function call, surrounding them with a
    second set of parentheses:

    sizeof ((int))

    doesn't create a more deeply nested parenthesized expression,
    since there was no parenthesized expression in the first place.
    Instead, in this case, it's a syntax error.

    A cast expression is another distinct use of parentheses in the language
    grammar:

    ( type-name ) cast-expression

    Although the parenthesized type-name in "sizeof (int)" and the parenthesized
    expression in "(int)expr" are visually similar, and probably deliberately so,
    they result from different grammar productions and are logically unrelated.
    The "(int)" prefix in "(int)expr" is informally referred to as a cast operator.
    The "(int)" in "sizeof (int)" is *not* a cast operator, it's a distinct
    case of a parenthesized type name.
     
    Keith Thompson, Mar 7, 2012
    #3
  4. [...]

    The "(int)" in "sizeof (int)" is not a "type cast". In fact, there's no
    such thing as a "type cast" in the C grammar.

    "(int) 42" is a cast-expression (C11 6.5.4), and the "(int)" prefix is
    informally referred to as a "cast operator".

    But the "(int)" in "sizeof (int)" is not a cast operator; it's merely
    part of the syntax of a unary-expression (C11 6.5.3):

    sizeof ( type-name )

    The parenthesized type-name in a cast-expression and the parenthesized
    type-name in a sizeof expression are visually similar, and that's
    probably not a coincidence, but in terms of the language grammar they're
    logically unrelated. (In both cases, there was a need to have a
    type-name in parentheses as part of an expression, and wrapping it in
    parentheses was an easy way to do that while avoiding ambiguity.)

    Strictly speaking, then "((int))" in "sizeof ((int))" is not anything at
    all; since it's a syntax error, you can't meaningfully say that it's any
    particular syntactic entity. For all we know, "int" could have been a
    misspelling of the identifier "hint".
     
    Keith Thompson, Mar 7, 2012
    #4
  5. Noob

    Nils M Holm Guest

    Indeed. I thought that the parens belong to a cast operator that form
    an operand of 'sizeof', but they are just part of the 'sizeof' syntax.
    Exactly my point.
     
    Nils M Holm, Mar 8, 2012
    #5
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.