Topic: The definite solution to operators' case
Author: avocado@risp.pl (Karol Kuczmarski)
Date: Fri, 30 Jul 2004 20:51:37 GMT Raw View
Dnia 26 lip 2004 o godzinie Pn, 26 lip 2004 20:58:59 GMT (GMT),
jpotter@falcon.lhup.edu (John Potter) napisal(a):
> On Sat, 24 Jul 2004 19:32:54 GMT, avocado@risp.pl (Karol Kuczmarski)
> wrote:
>
>> - If throw is an operator (I hope it's not :D), why return isn't?...
>> That's quite obvious generalisation...
>
> 15.1/3 should amuse you. The operand of throw is treated like the
> operand of a return statement. Since throw can be used in a
> subexpression and return can't, throw fits operator and return does
> not.
It can be used - but what for? As it was said, the expression with throw
cannot be evaluated and saved because of exception throwing. The
possibility of existence in complex expressions is therefore rather a
mistake. IMHO it would be better, if throw is treaten like return.
Of course I can be wrong, but if so, give me an reasonable example to use
throw in complex expression.
Regards,
Karol Kuczmarski
<avocado@risp.pl>
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: jpotter@falcon.lhup.edu (John Potter)
Date: Sat, 31 Jul 2004 06:09:19 GMT Raw View
On Fri, 30 Jul 2004 20:51:37 GMT, avocado@risp.pl (Karol Kuczmarski)
wrote:
> Of course I can be wrong, but if so, give me an reasonable example to use
> throw in complex expression.
Of course, reasonable is in the mind of the reasoner.
int x(a < b ? 42 : throw 69);
The authors of the standard seem to have a very broad acceptance of
what is reasonable.
John
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: avocado@risp.pl (Karol Kuczmarski)
Date: Sat, 24 Jul 2004 19:32:54 GMT Raw View
Howdy
I'm writing a C++ course e-book (not in English, unfortunately) and I want
to include there the operators' precedence & associativity table. You'll
ay: "What's the problem? There are plenty of it on the web". Yeah, that'
true. The problem is, that these tables are often ambigous, not clear or
even inconsistent. Too bad standard doesn't include such a table.
Therefore I decided to base on MSDN's table, which is, I think, the most
complete and clear. But I want to make it even better, so I bring here my
doubts about same things... Let's start.
- Is <> an operator? I think it's an operator in the same sense like the (0
parenthesis. (<> is used in *_cast and in templates). If so, what's the
prec. & assoc.? The same as () ?
- What about .template and ->template ? It can be treated in reference to .
and -> just like .* and ->* Of course, there are associated left to right,
but what's the priority?...
- The typename can also be an operator. Of course not the typename instead
of class in template arguments (where it indicates "the type of a type"),
but in dependent names. If this is an operator, it should have got
precedence below ::, <> and right-to-left assoc.
- Why throw is often meant to be an operator? The funny thing is that those
'operator' has higher precedence than comma, so in this expression:
(throw 5, 6)
the result should be 6. But that doesnt' solve the two problems. The
littlier: what's the result of "throw 5"? And the bigger: how the result of
expression above can be even saved (for example, in global variable, which
survives stack unwinding), when throw immediately throws an exception?
- If throw is an operator (I hope it's not :D), why return isn't?... That's
quite obvious generalisation...
That's all the problems - I hope :) I hope also, that in the (close) future
the C++ Standard will precisely define, what operator is, and include the
table of operators with its properties.
---------------------------
Karol Kuczmarski "Xion"
<avocado@risp.pl>
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: Alberto Barbati <AlbertoBarbati@libero.it>
Date: 26 Jul 2004 16:10:04 GMT Raw View
Karol Kuczmarski wrote:
> Howdy
>
> I'm writing a C++ course e-book (not in English, unfortunately) and I want
> to include there the operators' precedence & associativity table. You'll
> ay: "What's the problem? There are plenty of it on the web". Yeah, that'
> true. The problem is, that these tables are often ambigous, not clear or
> even inconsistent. Too bad standard doesn't include such a table.
The goal of the standard is to *specify* things, not to *explain*
things. A table such as the one you seek cannot be as precise as grammar
specifications so the standard only provides the latter. I think that's
the main reason why the tables you found are so ambiguous or
inconsistent ;-)
>
> - Is <> an operator? I think it's an operator in the same sense like the (0
> parenthesis. (<> is used in *_cast and in templates). If so, what's the
> prec. & assoc.? The same as () ?
It depends on how you define the term "operator". For example, according
to the standard (A.11), the *exhaustive* list of operators is the following:
new delete new[] delete[]
+ - * / % & |
! = < > += -= *= /= %=
= &= |= << >> >>= <<= == !=
<= >= && || ++ -- , ->* ->
() []
any other use of the word operator (for example: ":: is the scope
resolution operator") is improper. However, you may define the term
differently and still remain quite understandable.
I usually think of an operator as working on the "value" level. That is:
if you have a two expressions e1 and e2 that evaluates to a "value" you
can compose them by using a binary operator like in "e1 op e2" and get
another "value". Similarly for also unary operators. Notice that ?: is
used to make a "conditional expression" the term "ternary operator" is
improper (? and : are two distinct tokens and neither of them is
included in the list of operators)
<> works at a different level. Its "operands" are a "name" (on the left)
and expressions that evaluate to "types" (on the right), so, IMHO, it
does not qualify even informally as an operator. It doesn't make much
sense to talk about precedence here, unless you consider it at the
grammar level.
>
> - What about .template and ->template ? It can be treated in reference to .
> and -> just like .* and ->* Of course, there are associated left to right,
> but what's the priority?...
.template and ->template are just disambiguating versions of . and ->.
They have nothing to with .* and ->*. The right argument are of
different kind ("names" in the former case, "values" in the latter case).
>
> - The typename can also be an operator. Of course not the typename instead
> of class in template arguments (where it indicates "the type of a type"),
> but in dependent names. If this is an operator, it should have got
> precedence below ::, <> and right-to-left assoc.
As with <> I do not think of typename as an operator. It's relevance is
at a grammar/semantic level, not at the expression level. You cannot
talk about associativity at such level.
>
> - Why throw is often meant to be an operator? The funny thing is that those
> 'operator' has higher precedence than comma, so in this expression:
Although throw works on values, it still does not qualify to be an
operator, for the simple reason that it does *not* return any value
(technically, its type is void, but in fact a throw-expression never
return anything, because it affects the flow of control).
>
> (throw 5, 6)
>
> the result should be 6. But that doesnt' solve the two problems. The
> littlier: what's the result of "throw 5"? And the bigger: how the result of
> expression above can be even saved (for example, in global variable, which
> survives stack unwinding), when throw immediately throws an exception?
You just can't save it. The control is passed to a "handler" before the
value is ever computer or available to be saved.
>
> - If throw is an operator (I hope it's not :D), why return isn't?... That's
> quite obvious generalisation...
>
return was defined that way in the C language, so long ago. throw was
defined that way to allow it to be used in expressions such as "good ?
ok() : throw error". There was no point in modifying the definition of
return when throw was introduced. You should always see a programming
language as an evolution.
> That's all the problems - I hope :) I hope also, that in the (close) future
> the C++ Standard will precisely define, what operator is, and include the
> table of operators with its properties.
I'm happy with what the standard provides. Tables like this are for
books, not standards, but that's my personal opinion, which is far from
being important. If you can produce such a table, I suggest you to
submit it to the committee that may consider including it in an
informative (not normative) annex.
Regards,
Alberto
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: do-not-spam-benh@bwsint.com (Ben Hutchings)
Date: Mon, 26 Jul 2004 19:04:47 GMT Raw View
Karol Kuczmarski wrote:
> Howdy
>
> I'm writing a C++ course e-book (not in English, unfortunately) and I want
> to include there the operators' precedence & associativity table. You'll
> ay: "What's the problem? There are plenty of it on the web". Yeah, that'
> true. The problem is, that these tables are often ambigous, not clear or
> even inconsistent. Too bad standard doesn't include such a table.
>
> Therefore I decided to base on MSDN's table, which is, I think, the most
> complete and clear. But I want to make it even better, so I bring here my
> doubts about same things... Let's start.
For the benefit of those not familiar with the MSDN Library, this is
at
<http://msdn.microsoft.com/library/en-us/vclang/html/_pluslang_Lexical_Conventions.asp>.
> - Is <> an operator? I think it's an operator in the same sense like the (0
> parenthesis. (<> is used in *_cast and in templates). If so, what's the
> prec. & assoc.? The same as () ?
Angle-brackets are normally part of template-ids, which are resolved
to entities (functions or classes) at translation time, whereas
operators specify operations that may be evaluated at run time. (I
stress "may" because some operations may or must be evaluated at
translation time.) The same goes for the so-called scope resolution
operator, "::". The standard considers these to be part of id-
expressions (5.1/1).
The "*_cast<...>" operators should be considered separately, and
indeed they are listed in that table in their own right.
> - What about .template and ->template ? It can be treated in reference to .
> and -> just like .* and ->* Of course, there are associated left to right,
> but what's the priority?...
"template" used between a "." or "->" operator and an identifier is
just an aid to the parser to allow it to interpret template arguments
after the identifier correctly. It is not an operator.
> - The typename can also be an operator. Of course not the typename instead
> of class in template arguments (where it indicates "the type of a type"),
> but in dependent names. If this is an operator, it should have got
> precedence below ::, <> and right-to-left assoc.
Again this is an aid to the parser and not an operator.
> - Why throw is often meant to be an operator? The funny thing is that those
> 'operator' has higher precedence than comma, so in this expression:
>
> (throw 5, 6)
>
> the result should be 6. But that doesnt' solve the two problems. The
> littlier: what's the result of "throw 5"?
Nothing; its type is void.
> And the bigger: how the result of expression above can be even saved
> (for example, in global variable, which survives stack unwinding),
> when throw immediately throws an exception?
It can't, of course.
> - If throw is an operator (I hope it's not :D), why return isn't?... That's
> quite obvious generalisation...
That's what the grammar says. "return" can only be used as the
beginning of a return-statement whereas "throw" is used as part of a
throw-expression in an expression-statement (or as part of an
exception-specification).
The problem I see with making "return" an operator is that it might or
might not be followed by an expression depending on the return type of
the function. Operators generally aren't subject to such contextual
grammatical variation.
> That's all the problems - I hope :) I hope also, that in the (close) future
> the C++ Standard will precisely define, what operator is, and include the
> table of operators with its properties.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: jpotter@falcon.lhup.edu (John Potter)
Date: Mon, 26 Jul 2004 20:58:59 GMT Raw View
On Sat, 24 Jul 2004 19:32:54 GMT, avocado@risp.pl (Karol Kuczmarski)
wrote:
> I'm writing a C++ course e-book (not in English, unfortunately) and I want
> to include there the operators' precedence & associativity table. You'll
> ay: "What's the problem? There are plenty of it on the web". Yeah, that'
> true. The problem is, that these tables are often ambigous, not clear or
> even inconsistent. Too bad standard doesn't include such a table.
As Alberto states, that is not the job of the standard. As you have
noticed, it is also not possible. An excellent table can be found in
TC++PL. Stroustrup follows it with an example which shows that it does
not cover all cases.
a = b < c ? d = e : f = g;
a = (b < c) ? (d = e) : (f = g);
The assignements of d from e and f from g seem to have higher
precedence than ?: while the assignment to a seems to have lower
precedence.
Here is another.
a = b < c ? d , e : f , g;
(a = (b < c) ? (d , e) : f) , g;
The comma between d and e seems to have higher precedence than
?: while that between f and g seems to have lower precedence.
> - Is <> an operator?
No. It is not used in expression to perform an operation.
> I think it's an operator in the same sense like the ()
> parenthesis.
It is not and not all () is an operator. () is the function
call operator.
a = (b + c) * (d + e);
The parentheses in that statement and the second forms above
are punctuators not the function call operator.
x = pow(a, b);
The comma in that statement is a punctuator not the comma
operator. The parentheses are the function call operator.
> - If throw is an operator (I hope it's not :D), why return isn't?... That's
> quite obvious generalisation...
15.1/3 should amuse you. The operand of throw is treated like the
operand of a return statement. Since throw can be used in a
subexpression and return can't, throw fits operator and return does not.
John
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: musiphil@bawi.org (Seungbeom Kim)
Date: Mon, 26 Jul 2004 21:33:11 GMT Raw View
Alberto Barbati wrote:
> It depends on how you define the term "operator". For example, accordin=
g=20
> to the standard (A.11), the *exhaustive* list of operators is the=20
> following:
>=20
> new delete new[] delete[]
> + - * / % =88 & | =98
> ! =3D < > +=3D -=3D *=3D /=3D %=3D
> =88=3D &=3D |=3D << >> >>=3D <<=3D =3D=3D !=3D
> <=3D >=3D && || ++ -- , ->* ->
> () []
>=20
> any other use of the word operator (for example: ":: is the scope=20
> resolution operator") is improper. However, you may define the term=20
> differently and still remain quite understandable.
The list that you quoted here specifies only those which can come after=20
the keyword "operator" to form an operator-function-id. It's not an=20
exhaustive list of operators. The standard doesn't seem to define the=20
precise meaning of operator, but it does mention ::, sizeof, typeid, and=20
even #, ## as operators.
> I usually think of an operator as working on the "value" level. That is=
:=20
> if you have a two expressions e1 and e2 that evaluates to a "value" you=
=20
> can compose them by using a binary operator like in "e1 op e2" and get=20
> another "value". Similarly for also unary operators. Notice that ?: is=20
> used to make a "conditional expression" the term "ternary operator" is=20
> improper (? and : are two distinct tokens and neither of them is=20
> included in the list of operators)
Your explanation seems to be a common one, but it fails to explain the=20
case of ptr->member; ptr is a value, but member is not. And the case of=20
new int; int is not a value but a type-id.
And I don't see how the fact that ? and : are two distinct tokens makes=20
the term "ternary operator" improper; we say new[] is an operator though=20
in "new int[2]" new, [, and ] are all distinct tokens. So is ?:, and=20
what else than ternary could it be?
--=20
Seungbeom Kim
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: jpotter@falcon.lhup.edu (John Potter)
Date: Mon, 26 Jul 2004 21:33:28 GMT Raw View
On 26 Jul 2004 16:10:04 GMT, Alberto Barbati <AlbertoBarbati@libero.it>
wrote:
> It depends on how you define the term "operator".
Yes.
> For example, according
> to the standard (A.11), the *exhaustive* list of operators
No.
That is the list of symbols which may be substituted for the
non-terminal <operator> which follows the key word "operator"
in the grammar. It does not define the word operator as used
in the C++ standard. That list does not include the operators
which may not be overloaded.
5.2.7/1 ... The dynamic_cast operator ...
5.3.3/1 The sizeof operator ...
13.5/3 The following operators cannot be overloaded:
. .* :: ?:
I think the rest of your post nicely states that operators
are those things which are used in expressions to perform
operations. The term operator is not defined in the standard.
John
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: sk@bez.spamu.z.pl (Sebastian Kaliszewski)
Date: Wed, 28 Jul 2004 18:56:27 GMT Raw View
Ben Hutchings wrote:
[snip]
>>- If throw is an operator (I hope it's not :D), why return isn't?... That's
>>quite obvious generalisation...
>
>
> That's what the grammar says. "return" can only be used as the
> beginning of a return-statement whereas "throw" is used as part of a
> throw-expression in an expression-statement (or as part of an
> exception-specification).
>
> The problem I see with making "return" an operator is that it might or
> might not be followed by an expression depending on the return type of
> the function. Operators generally aren't subject to such contextual
> grammatical variation.
Well, throw doesn't have to either:
catch(my_exception &x)
{
x.do_sth();
throw;
}
rgds
--
Sebastian Kaliszewski
--
"Never underestimate the power of human stupidity" -- from Notebooks of LL
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]