Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #18285 > unrolled thread

sizeof((type)) is a constraint violation?

Started byNoob <root@127.0.0.1>
First post2012-03-07 14:58 +0100
Last post2012-03-07 12:44 -0800
Articles 6 — 4 participants

Back to article view | Back to comp.lang.c


Contents

  sizeof((type)) is a constraint violation? Noob <root@127.0.0.1> - 2012-03-07 14:58 +0100
    Re: sizeof((type)) is a constraint violation? Nils M Holm <news2009@t3x.org> - 2012-03-07 14:47 +0000
      Re: sizeof((type)) is a constraint violation? Keith Thompson <kst-u@mib.org> - 2012-03-07 12:51 -0800
        Re: sizeof((type)) is a constraint violation? Nils M Holm <news2009@t3x.org> - 2012-03-08 06:15 +0000
    Re: sizeof((type)) is a constraint violation? China Blue Water Navy <chine.bleu@yahoo.com> - 2012-03-07 07:11 -0800
    Re: sizeof((type)) is a constraint violation? Keith Thompson <kst-u@mib.org> - 2012-03-07 12:44 -0800

#18285 — sizeof((type)) is a constraint violation?

FromNoob <root@127.0.0.1>
Date2012-03-07 14:58 +0100
Subjectsizeof((type)) is a constraint violation?
Message-ID<jj7phr$ghu$1@dont-email.me>
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.

[toc] | [next] | [standalone]


#18288

FromNils M Holm <news2009@t3x.org>
Date2012-03-07 14:47 +0000
Message-ID<9rpaohFc5sU1@mid.individual.net>
In reply to#18285
Noob <root@127.0.0.1> wrote:
> Obviously, the compiler dislikes the double parenthesis
> around a type-name.
> 
> Does this mean ((int)) cannot be takes as a unary-expression?

((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.

> However ((x)) or ((42)) are valid instances of unary-expression?

These, on the other hand, /are/ primary expressions.

-- 
Nils M Holm  < n m h @ t 3 x . o r g >  www.t3x.org

[toc] | [prev] | [next] | [standalone]


#18304

FromKeith Thompson <kst-u@mib.org>
Date2012-03-07 12:51 -0800
Message-ID<lnboo85e4n.fsf@nuthaus.mib.org>
In reply to#18288
Nils M Holm <news2009@t3x.org> writes:
> Noob <root@127.0.0.1> wrote:
>> Obviously, the compiler dislikes the double parenthesis
>> around a type-name.
>> 
>> Does this mean ((int)) cannot be takes as a unary-expression?
>
> ((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).
[...]

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 (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
    Will write code for food.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#18315

FromNils M Holm <news2009@t3x.org>
Date2012-03-08 06:15 +0000
Message-ID<9rr14jFpl8U1@mid.individual.net>
In reply to#18304
Keith Thompson <kst-u@mib.org> wrote:
> 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 )

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.

> Strictly speaking, then "((int))" in "sizeof ((int))" is not anything at
> all; [...]

Exactly my point.

-- 
Nils M Holm  < n m h @ t 3 x . o r g >  www.t3x.org

[toc] | [prev] | [next] | [standalone]


#18290

FromChina Blue Water Navy <chine.bleu@yahoo.com>
Date2012-03-07 07:11 -0800
Message-ID<chine.bleu-D953EE.07115107032012@news.eternal-september.org>
In reply to#18285
In article <jj7phr$ghu$1@dont-email.me>, Noob <root@127.0.0.1> wrote:

> 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?

type-name:
    specifier-qualifier-list abstract-declaratoropt
abstract-declarator:
    pointer
    | pointeropt direct-abstract-declarator
direct-abstract-declarator:
    ( abstract-declarator )
    | direct-abstract-declaratoropt [ assignment-expressionopt ]              
    | direct-abstract-declaratoropt [ * ]
    | direct-abstract-declaratoropt ( parameter-type-listopt )

So you can pile up any number of parentheses, but you have to put something else 
inside them like *, [...], (...).

-- 
My name Indigo Montoya.      |    R'lyeh 38o57'6.5''S 102o51'16''E.
You flamed my father.        |       I'm whoever you want me to be.
Prepare to be spanked.       |  Annoying Usenet one post at a time.
Stop posting that!           |    At least I can stay in character.

[toc] | [prev] | [next] | [standalone]


#18303

FromKeith Thompson <kst-u@mib.org>
Date2012-03-07 12:44 -0800
Message-ID<lnfwdk5ef3.fsf@nuthaus.mib.org>
In reply to#18285
Noob <root@127.0.0.1> writes:
> 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.
[...]

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 (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
    Will write code for food.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c


csiph-web