Topic: sizeof needs higher precedence... or does it?


Author: kuyper@wizard.net
Date: Tue, 10 Oct 2006 13:29:19 CST
Raw View
Frederick gotham wrote:
> kanze posted:
.
> > In modern C and C++, the grammar rules are such that
> > `(int)-1' is an "cast-expression" (a non-terminal which doesn't
> > exist in K&R C), and there is no reduction for `sizeof'
> > cast-expression.  So the second possibility fails to parse.
>
>
> So it's the whole "unary expression" Vs "cast expression" that makes the
> difference. . . ?

Exactly.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: kuyper@wizard.net
Date: Tue, 10 Oct 2006 13:29:04 CST
Raw View
Frederick Gotham wrote:
> Greg Herlihy posted:
>
> >     struct A
> >     {
> >         A operator-() const
> >         {
> >             std::cout << "in unary negation\n";
> >
> >             return *this;
> >         }
> >     };
> >
> >     int operator-(int lhs, const A& rhs)
> >     {
> >         std::cout << "in binary subtraction\n";
> >         return 0;
> >     }
> >
> >     int main()
> >     {
> >         A a;
> >
> >         sizeof(int) - a;
> >     }
> >
> > And it should not be to anyone's surprise (who followed the explanation
> > above) that this program prints out "in binary subtraction".
>
>
> That experiment would be more meaningful if you were to define:
>
>     A::operator int
>
> Anywho, it's no good to draw a direct analogy between built-in operators
> and user-defined operators -- as we've seen them work differently more than
> once.

Expressions involving operator overloads are parsed exactly as if they
weren't overloaded, it's only the semantics that are different.
Therefore, if you determine which operator overloads get called, you
determine how that particular implementation parses such expressions.
However, such experiments can answer questions about what the standard
requires only if you're willing to assume that the implementation
you're using is perfectly conforming.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "kanze" <kanze@gabi-soft.fr>
Date: Wed, 11 Oct 2006 10:24:02 CST
Raw View
Frederick gotham wrote:
> kanze posted:

    [...]
> > In modern C and C++, the grammar rules are such that
> > `(int)-1' is an "cast-expression" (a non-terminal which doesn't
> > exist in K&R C), and there is no reduction for `sizeof'
> > cast-expression.  So the second possibility fails to parse.

> So it's the whole "unary expression" Vs "cast expression" that
> makes the difference. . . ?

More or less.  It's basically that the standard definition of
C++ doesn't have precedance, as such, but rather a large number
of productions, with a large number of intermediate
non-terminals.  And given your expression, there's only one set
of reductions which will get you from the terminals to the non
terminal expression.  If the cast-expression were unified with
unary-expression (as they are in K&R1), then I think your
interpretation would be possible, and the grammar would be
ambiguous.  In fact, I wouldn't be surprised if the reason the C
committee introduced the additional non-terminal cast-expression
were because someone before you recognized the ambiguity, and
that this was the C committee's means of resolving it.  (In this
case, of course, the C++ standard is just a copy of the C
standard.)

--
James Kanze                                           GABI Software
Conseils en informatique orient   e objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place S   mard, 78210 St.-Cyr-l'   cole, France, +33 (0)1 30 23 00 34


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: fgothamNO@SPAM.com (Frederick Gotham)
Date: Sun, 8 Oct 2006 18:17:48 GMT
Raw View
Greg Herlihy posted:

> In the expression:
>
>     sizeof(int) - 1
>
> there is one operator, "-", and two operands, "sizeof(int)" and "1". So
> there is no unary negation taking place, only binary subtraction.


Not according to the Standard (as _I_ read it at present in anyway).

The reason I started this thread is because I believe that the expression
is an ambiguous parse, and so operator precedence and associativity must
come into play.

>From what I see, it could be interpreted as either:

      sizeof
        /
     (int)
      /
     - unary
    /
   1

or:
            - binary
           / \
          /   \
         /     \
      sizeof    1
        /
     (int)

Looking at my operator table, I see that "sizeof", cast, and unary minus
all have the same precedence, and that they bind from right-to-left.

Because they bind from right to left, I think sizeof(int)-1 should evaluate
to the former example above, rather than the latter.

Because it is commonly excepted that "sizeof(int) - 1" should do the latter
rather than the former, I can only conclude that the Standard has a defect
in that "sizeof" should have higher precedence.

--

Frederick Gotham

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "James Kanze" <kanze.james@neuf.fr>
Date: Sun, 8 Oct 2006 13:17:36 CST
Raw View
Frederick Gotham wrote:
> Let's say we want to take the size of the int data type, and
> then subtract one from it:

>     sizeof(int) - 1

> If I consult my operator precedence table, I see that the
> following three operators have equal precedence, and that they
> bind from right to left:

>     Unary negation
>     Parenthesised type name cast operator
>     sizeof

Except that this is false.  Sizeof and unary negation have
higher precedence than an "explicit type conversion (cast
notation)".  At least according to the C++ standard.

(At least in a first approximation.  The rules are actually more
complex, and cannot be described by simple precedance.)

> This would lead me to belive that the above expression should
> be parsed as:

>     sizeof(  (int)-1  )

> (i.e. -1 is cast to an int, and then passed on to sizeof.)

According to the standard, sizeof requires a "unary-expression"
as an operand, and (int)-1 is not a unary expression, but a
cast-expression.

Interestingly, "sizeof -(int)-1" is legal, and has the same
meaning as "sizeof(-(int)-1)".  This is because a
"unary-operator" (one of &, *, +, -, ~ or !) can be followed by
a cast-expression to form a unary expression.  This is an
example of a case where the C++ rules cannot be described by
simple precedance: the expansion of cast-expression involves a
unary-expression, and certain expansions of unary-expression
involve cast-expression.

Note that in this case, C++ follows the standard C 90, which
differs from K&R C.

--
James

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: jm@bourguet.org (Jean-Marc Bourguet)
Date: Sun, 8 Oct 2006 20:32:13 GMT
Raw View
fgothamNO@SPAM.com (Frederick Gotham) writes:

> Greg Herlihy posted:
>
>> In the expression:
>>
>>     sizeof(int) - 1
>>
>> there is one operator, "-", and two operands, "sizeof(int)" and "1". So
>> there is no unary negation taking place, only binary subtraction.
>
>
> Not according to the Standard (as _I_ read it at present in anyway).
>
> The reason I started this thread is because I believe that the expression
> is an ambiguous parse, and so operator precedence and associativity must
> come into play.
>
>>From what I see, it could be interpreted as either:
>
>       sizeof
>         /
>      (int)
>       /
>      - unary
>     /
>    1
>
> or:
>             - binary
>            / \
>           /   \
>          /     \
>       sizeof    1
>         /
>      (int)

sizeof does not takes a cast expression but an unary expression, your first
interpretation would have sizeof with an argument which is a cast
expression, so it is not a valid parse.

A+

--
Jean-Marc

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: jdennett@acm.org (James Dennett)
Date: Sun, 8 Oct 2006 22:42:23 GMT
Raw View
Frederick Gotham wrote:
> Greg Herlihy posted:
>
>> In the expression:
>>
>>     sizeof(int) - 1
>>
>> there is one operator, "-", and two operands, "sizeof(int)" and "1". So
>> there is no unary negation taking place, only binary subtraction.
>
>
> Not according to the Standard (as _I_ read it at present in anyway).
>
> The reason I started this thread is because I believe that the expression
> is an ambiguous parse, and so operator precedence and associativity must
> come into play.
>
>>From what I see, it could be interpreted as either:
>
>       sizeof
>         /
>      (int)
>       /
>      - unary
>     /
>    1
>
> or:
>             - binary
>            / \
>           /   \
>          /     \
>       sizeof    1
>         /
>      (int)
>
> Looking at my operator table, I see that "sizeof", cast, and unary minus
> all have the same precedence, and that they bind from right-to-left.

This is the core of the problem you're having; there is NO valid
"precedence" table for C++ expressions.  The grammar does not
correspond to any precedence table, and questions on how to
parse expressions need to be answered based on the grammar, not
on some approximate precedence table.

-- James

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: kuyper@wizard.net
Date: Sun, 8 Oct 2006 17:43:11 CST
Raw View
Frederick Gotham wrote:
> Greg Herlihy posted:
>
> > In the expression:
> >
> >     sizeof(int) - 1
> >
> > there is one operator, "-", and two operands, "sizeof(int)" and "1". So
> > there is no unary negation taking place, only binary subtraction.
>
>
> Not according to the Standard (as _I_ read it at present in anyway).
>
> The reason I started this thread is because I believe that the expression
> is an ambiguous parse, and so operator precedence and associativity must
> come into play.
>
> >From what I see, it could be interpreted as either:
>
>       sizeof
>         /
>      (int)
>       /
>      - unary
>     /
>    1
>
> or:
>             - binary
>            / \
>           /   \
>          /     \
>       sizeof    1
>         /
>      (int)
>
> Looking at my operator table, I see that "sizeof", cast, and unary minus
> all have the same precedence, and that they bind from right-to-left.

If you're reading something that describes C++ in terms of precedence
and binding, what you're reading isn't the C++ standard, it's a summary
of it. The C++ standard describes all of these issues in terms of
grammar rules. The content of many of those rules can be described with
moderate accuracy in terms of precedence and associativity, but no such
description can be completely correct.

However, in this case, the problem isn't that the relevant rules can't
be described that way. The problem is that the precedence table you're
looking at isn't correct. This may be due in part to confusion between
C-style casts and named casts, such as static_cast<int>, The relevant
grammar rules are:

postfix-expression:
    static_cast<type-id> (expression)

unary-operator:
    -

unary-expression:
    postfix-expression
   sizeof unary-expression
   unary-operator cast-expression
   sizeof (type-id)

cast-expression:
    unary-expression
    (type-id) cast-expression

This subset of the rules can be described in terms of precedence, and
the order of precedence, from highest to lowest, implied by those rules
is:

static_cast
sizeof
C-style cast
unary minus

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Alberto Ganesh Barbati <AlbertoBarbati@libero.it>
Date: Sun, 8 Oct 2006 18:28:33 CST
Raw View
Frederick Gotham ha scritto:
>
> Looking at my operator table, I see that "sizeof", cast, and unary minus
> all have the same precedence, and that they bind from right-to-left.
>
> Because they bind from right to left, I think sizeof(int)-1 should evaluate
> to the former example above, rather than the latter.
>
> Because it is commonly excepted that "sizeof(int) - 1" should do the latter
> rather than the former, I can only conclude that the Standard has a defect
> in that "sizeof" should have higher precedence.

You are blaming the wrong horse. The right conclusion is that your
operator table, onto which you base all your argument, does not describe
correctly what it's happening. If there's a defect, it's in the table,
not in the standard. See my other post for details.

Ganesh

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Greg Herlihy" <greghe@pacbell.net>
Date: Sun, 8 Oct 2006 21:07:27 CST
Raw View

On Oct 8, 11:17 am, fgotha...@SPAM.com (Frederick Gotham) wrote:
> Greg Herlihy posted:
>
> > In the expression:
>
> >     sizeof(int) - 1
>
> > there is one operator, "-", and two operands, "sizeof(int)" and "1". So
> > there is no unary negation taking place, only binary subtraction.Not according to the Standard (as _I_ read it at present in anyway).

In order for the sizeof(int) - 1 to be a valid C++ expression it must
match one of the productions of the C++ grammar. These productions
appear throughout that Standard and are conveniently summarized in
Appendix A. Now if the minus sign is a unary operator, then the
sizeof(int) - 1 expression would reduce to:

    unary-expression unary-expression

in other words, two unary expressions with nothing in between them.
There is no production in the C++ grammar that matches this syntax, so
it is not a valid C++ expression - any more than the expression:

     sizeof(int) 1;

is a valid C++ expression. In fact, there is only one grammatical
production in the C++ that does match:

    additive-expression:
          additive-expression - multiplicative-expression

Now there are two ways to confirm that this production describes the
original expression: either by "reducing" this production to arrive at
the original expression, or by applying productions to the original
expression to arrive at this production. Let's take the latter
approach.

Starting with the left side of the original expression, we apply this
production to the sizeof(int) token:

    unary-expression:
        sizeof '(' type-id ')'

and then apply this production for the unary-expression:

    cast-expression:
        unary-expression

By applying a series of productions: the cast-expression becomes a
pm-expression, the pm-expression becomes a multiplicative-expression,
and a multiplicative expression is turned into an additive expression.
So "sizeof(int)" is really a form of an additive expression in the C++
grammar.

Evaluating the righthand side of the expression, "1", follows a similar
path: starting with the integer-literal production, the following
productions are applied in turn: integer-literal to literal, literal to
primary-expression, primary-expression to postfix-expression, post-fix
to unary-expression and from there it follows the same path as before
until mulitplicative expression. So the "1" it turns out is a type of
multiplicative expression in C++.

Having done all that work (compiling a C++ program by hand is quite
tedious actually) we have: an additive-expression on the left, a
multiplicative-expression on the right, and a minus character between
them. Which means the original expression is exactly what it looks
like: subtraction.

Now, for anyone who prefers the scientific method, we can design an
experiment to give us the same answer: replace the "1" operand with a
class object that overloads both the unary negation and binary
subtraction operators and see which one is called:

    struct A
    {
        A operator-() const
        {
            std::cout << "in unary negation\n";

            return *this;
        }
    };

    int operator-(int lhs, const A& rhs)
    {
        std::cout << "in binary subtraction\n";
        return 0;
    }

    int main()
    {
        A a;

        sizeof(int) - a;
    }

And it should not be to anyone's surprise (who followed the explanation
above) that this program prints out "in binary subtraction".

Greg

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "kanze" <kanze@gabi-soft.fr>
Date: Mon, 9 Oct 2006 10:15:45 CST
Raw View
Greg Herlihy wrote:
> On Oct 7, 10:41 pm, fgotha...@SPAM.com (Frederick Gotham) wrote:
> > Let's say we want to take the size of the int data type, and
> > then subtract one from it:

> >     sizeof(int) - 1

> > If I consult my operator precedence table, I see that the
> > following three operators have equal precedence, and that
> > they bind from right to left:

> >     Unary negation
> >     Parenthesised type name cast operator
> >     sizeof

> > This would lead me to belive that the above expression should be parsed as:

> >     sizeof(  (int)-1  )

> > (i.e. -1 is cast to an int, and then passed on to sizeof.)

> In the expression:

>     sizeof(int) - 1

> there is one operator, "-", and two operands, "sizeof(int)"
> and "1". So there is no unary negation taking place, only
> binary subtraction.

That's true, but how do we know this?  I'm pretty sure that
Frederick knows that this is how his compiler interprets it, but
he is asking why.

There's a long standing ambigu   ty in most languages, in that
unary and binary minus are represented by the same symbol,
dispite having different precedances and different semantics.
Normally, the langage depends on the fact that in any given
context, only one interpretation is possible, and uses it.  In
the case of K&R C, in an expression like "sizeof( int )
- 1", two different parses are possible:

           -
          / \
         /   \
    sizeof    1
       |
       |
     (int)

and

        sizeof
          |
          |
        (int)
          |
          |
          -
          |
          |
          1

due to the fact that both the `-' and `(int)' can be interpreted
in different ways.  I'm not sure how K&R C disambiguated this,
but in modern C and C++, the grammar rules are such that
`(int)-1' is an "cast-expression" (a non-terminal which doesn't
exist in K&R C), and there is no reduction for `sizeof'
cast-expression.  So the second possibility fails to parse.

--
James Kanze                                           GABI Software
Conseils en informatique orient   e objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place S   mard, 78210 St.-Cyr-l'   cole, France, +33 (0)1 30 23 00 34


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: jm@bourguet.org (Jean-Marc Bourguet)
Date: Mon, 9 Oct 2006 16:10:23 GMT
Raw View
fgothamNO@SPAM.com (Frederick Gotham) writes:

> Let's say we want to take the size of the int data type, and then subtract
> one from it:
>
>     sizeof(int) - 1
>
> If I consult my operator precedence table, I see that the following three
> operators have equal precedence, and that they bind from right to left:
>
>     Unary negation
>     Parenthesised type name cast operator
>     sizeof
> This would lead me to belive that the above expression should be parsed as:
>
>     sizeof(  (int)-1  )
>
> (i.e. -1 is cast to an int, and then passed on to sizeof.)

1/ The grammar is not described in term of operator precedence, and it is
clear that it must be parsed (sizeof(int)) - 1.

2/ Pay attention when thinking about operator precedence, because unary
minus has higher precedence than soustraction, you could conclude that
   a - b
is not valid because the - is an unary minus...  The catch is that operator
precedence is a way of *resolving ambiguities* in a grammar.  In cases
where there is no ambiguitites (like this one), precedence don't play a
role at all.

Yours,

--
Jean-Marc

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Frederick Gotham <fgothamNO@SPAM.com>
Date: Tue, 10 Oct 2006 11:19:04 CST
Raw View
Greg Herlihy posted:

>     struct A
>     {
>         A operator-() const
>         {
>             std::cout << "in unary negation\n";
>
>             return *this;
>         }
>     };
>
>     int operator-(int lhs, const A& rhs)
>     {
>         std::cout << "in binary subtraction\n";
>         return 0;
>     }
>
>     int main()
>     {
>         A a;
>
>         sizeof(int) - a;
>     }
>
> And it should not be to anyone's surprise (who followed the explanation
> above) that this program prints out "in binary subtraction".


That experiment would be more meaningful if you were to define:

    A::operator int

Anywho, it's no good to draw a direct analogy between built-in operators
and user-defined operators -- as we've seen them work differently more than
once.

--

Frederick Gotham

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: fgothamNO@SPAM.com (Frederick gotham)
Date: Tue, 10 Oct 2006 17:14:43 GMT
Raw View
kanze posted:

> That's true, but how do we know this?  I'm pretty sure that
> Frederick knows that this is how his compiler interprets it, but
> he is asking why.


Exactly.


> In modern C and C++, the grammar rules are such that
> `(int)-1' is an "cast-expression" (a non-terminal which doesn't
> exist in K&R C), and there is no reduction for `sizeof'
> cast-expression.  So the second possibility fails to parse.


So it's the whole "unary expression" Vs "cast expression" that makes the
difference. . . ?

--

Frederick Gotham

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: fgothamNO@SPAM.com (Frederick Gotham)
Date: Sun, 8 Oct 2006 05:41:07 GMT
Raw View
Let's say we want to take the size of the int data type, and then subtract
one from it:

    sizeof(int) - 1

If I consult my operator precedence table, I see that the following three
operators have equal precedence, and that they bind from right to left:

    Unary negation
    Parenthesised type name cast operator
    sizeof

This would lead me to belive that the above expression should be parsed as:

    sizeof(  (int)-1  )

(i.e. -1 is cast to an int, and then passed on to sizeof.)

--

Frederick Gotham

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Greg Herlihy" <greghe@pacbell.net>
Date: Sun, 8 Oct 2006 09:16:25 CST
Raw View

On Oct 7, 10:41 pm, fgotha...@SPAM.com (Frederick Gotham) wrote:
> Let's say we want to take the size of the int data type, and then subtract
> one from it:
>
>     sizeof(int) - 1
>
> If I consult my operator precedence table, I see that the following three
> operators have equal precedence, and that they bind from right to left:
>
>     Unary negation
>     Parenthesised type name cast operator
>     sizeof
>
> This would lead me to belive that the above expression should be parsed as:
>
>     sizeof(  (int)-1  )
>
> (i.e. -1 is cast to an int, and then passed on to sizeof.)

In the expression:

    sizeof(int) - 1

there is one operator, "-", and two operands, "sizeof(int)" and "1". So
there is no unary negation taking place, only binary subtraction.

Greg

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: AlbertoBarbati@libero.it (Alberto Ganesh Barbati)
Date: Sun, 8 Oct 2006 15:35:08 GMT
Raw View
Frederick Gotham ha scritto:
> Let's say we want to take the size of the int data type, and then subtract
> one from it:
>
>     sizeof(int) - 1
>
> If I consult my operator precedence table, I see that the following three
> operators have equal precedence, and that they bind from right to left:
>
>     Unary negation
>     Parenthesised type name cast operator
>     sizeof
>

There is no operator precedence table in the C++ standard: operator
precedence is implicitly defined by the syntax grammar. Several people
tried to derive precedence tables from the grammar because they are
easier to understand and remember, but a table can't correctly express
parsing choices, as in this case.

A unary-expression starting with a sizeof token can either be a:

   sizeof unary-expression
   sizeof (type-id)

but "(int)-1" is not a unary-expression (it's a cast-expression) so that
leaves only the second parsing possibility. So first "sizeof(int)" is
parsed as a unary-expression and then the rest of the tokens is considered.

Notice that it would be wrong to say that sizeof has the precedence over
the cast operator, in this case, because there's *no* cast operator in
the correctly parsed expression!

Regards,

Ganesh

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]