Topic: sizeof in integral constant expressions [Thanks!!!]
Author: Christopher Eltschka <celtschk@dollywood.itp.tuwien.ac.at>
Date: Tue, 3 Apr 2001 23:02:50 GMT Raw View
Stephen Howe wrote:
>
> "Anon" <spamme@lots.UCAR.EDU> wrote in message
> news:3a9d728c_2@news.nwlink.com...
>
> Perhaps it shuld be stated that sizeof() is a compile-time operator and
> AFAIK, the only one that is (with the exception of C's VLAs). The compiler
> just replaces sizeof(expression) with a number that is the size.
AFAIK, typeid has an even more interesting behaviour: It evaluates it's
expression exactly if its static type is a polymorphic type.
Example:
template<class T> bool is_polymorphic()
{
bool result = false;
typeid(result = true, T());
return result;
}
class X {};
class Y { virtual ~Y() {} }
int main()
{
assert( !is_polymorphic<X>() && is_polymorphic<Y>() );
}
---
[ 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.research.att.com/~austern/csc/faq.html ]
Author: Martin Sebor <sebor@roguewave.com>
Date: Thu, 5 Apr 2001 15:18:20 GMT Raw View
Christopher Eltschka wrote:
>
...
>
> AFAIK, typeid has an even more interesting behaviour: It evaluates it's
> expression exactly if its static type is a polymorphic type.
>
> Example:
>
> template<class T> bool is_polymorphic()
> {
> bool result = false;
> typeid(result = true, T());
> return result;
> }
Fascinating, although you will want to replace T() with an lvalue
for this to work.
Regards
Martin
---
[ 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.research.att.com/~austern/csc/faq.html ]
Author: "Andrea Ferro" <AndreaF@UrkaDVD.it>
Date: Thu, 5 Apr 2001 22:18:05 GMT Raw View
"Christopher Eltschka" <celtschk@dollywood.itp.tuwien.ac.at> wrote in message
news:3AC9F9B6.57440926@dollywood.itp.tuwien.ac.at...
...
> AFAIK, typeid has an even more interesting behaviour: It evaluates it's
> expression exactly if its static type is a polymorphic type.
>
> Example:
>
> template<class T> bool is_polymorphic()
> {
> bool result = false;
> typeid(result = true, T());
> return result;
> }
>
> class X {};
> class Y { virtual ~Y() {} }
>
> int main()
> {
> assert( !is_polymorphic<X>() && is_polymorphic<Y>() );
> }
I see two problems here.
One is that according to what I think you would expect to happen, since Y is
polimorfic the expression is to be evaluated for it. But this constructs a Y
object and the destructor is private (not accessible).
As is your example shuld not compile on any implementation.
The other is that, even if you make the destructor public (and this is the real
problem) an explicit call to the constructor results in an rvalue. And typeid
will only work the way you expect with lvalues. Therefore it will probably not
work as expected.
This would, however:
template<class T> bool is_polymorphic( const T&r )
{
bool result = false;
typeid(result = true, r);
return result;
}
struct X {};
struct Y { virtual ~Y() {} }
int main()
{
assert( !is_polymorphic(X()) && is_polymorphic(Y()) );
}
Andrea Ferro
---------
Brainbench C++ Master. Scored higher than 97% of previous takers
Scores: Overall 4.46, Conceptual 5.0, Problem-Solving 5.0
More info http://www.brainbench.com/transcript.jsp?pid=2522556
---
[ 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.research.att.com/~austern/csc/faq.html ]
Author: clarkcox3@yahoo.com (Clark S. Cox, III)
Date: Sun, 4 Mar 2001 20:22:14 GMT Raw View
Marcin 'Qrczak' Kowalczyk <qrczak@knm.org.pl> wrote:
> Thu, 1 Mar 2001 21:21:59 GMT, Clark S. Cox, III <clarkcox3@yahoo.com> pisze:
>
> > > In any case, (expr1) * (expr2) should always evaluate both expressions.
> >
> > No, if one of the expressions evaluates to zero, and the other has
> > no side effects, a compiler is free to omit the evaluation of the other
> > expression.
>
> In this case no program can tell the difference, so obviously the
> compiler can compile in any way it wants. We are talking about the
> meaning of a program, not about the way it can be compiled, i.e. about
> cases when it does make a difference.
in cases where it does make a difference, they must both be
evaluated, as an example:
#include <cmath>
....
double d = 0;
double e = d * std::sqrt(-1); // 0 * NaN isn't always 0
--
http://www.whereismyhead.com/clark/
Clark S. Cox, III
clarkcox3@yahoo.com
---
[ 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.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: "Deja User" <gennaro_prota@my-deja.com>
Date: Thu, 22 Feb 2001 19:35:47 GMT Raw View
On Thu, 22 Feb 2001 13:08:13 GMT, "James Kuyper Jr." <kuyper@wizard.net> wrote:
>
>I'm talking about "function-call operators" because 5.19 does: it says
>that "function-call ... operators shall not be used" in constant
>expressions. Now, there is no such thing as a function-call operator in
>the syntactic sense: in "f()", 'f' is the function name, and '()' are
>parentheses, and syntactically the whole thing is a function-call
>exression.
What a joy! :-))) Thanks! Now I think the mystery is cleared up!
First of all, I want to say that I was puzzled about the fact that the
standard SEEMED (to me) to prohibit
int f();
int array[sizeof(f())];
I agree with you that there's no reason why it should be illegal.
Now, I know that it is NOT illegal.
My confusion regarded the fact that, when reading the list
"...and assignment, increment, decrement, function-call, or comma operators shall
not be used", I didn't notice that the noun "operator" refers to all "assignment, increment,
decrement and function call". In other words I saw it as:
- assignment is prohibited
- increment and decrement are prohibited.
- function-call is prohibited.
The last was interpreted by me as 'function call expression' is prohibited (since 5.19 refers to
expressions) and not as 'function call operator' is prohibited!
Shame on me! :-(((
> The only sense in which function-call operators exist is
>semantic, in which case the term refers to the function that will be
>executed if the corresponding expression is evaluated. Using an operator
>in that sense refers to the execution of the function, not the writing
>down of the expression. Since the function-call expression occurs inside
>the sizeof() expression, it never gets evaluated, and therefore the
>corresponding function-call operator is not used. That distinction is
>crucial to my argument.
Yes, now it's very clear to me!
Thanks a lot for being so patient! :-)))
Gennaro Prota.
------------------------------------------------------------
--== Sent via Deja.com ==--
http://www.deja.com/
---
[ 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.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: "Anon" <uunet!lots!spamme@ncar.UCAR.EDU>
Date: Mon, 26 Feb 2001 21:50:03 GMT Raw View
> On Thu, 22 Feb 2001 13:08:13 GMT, "James Kuyper Jr." <kuyper@wizard.net>
wrote:
> >I'm talking about "function-call operators" because 5.19 does: it says
> >that "function-call ... operators shall not be used" in constant
> >expressions. Now, there is no such thing as a function-call operator in
> >the syntactic sense: in "f()", 'f' is the function name, and '()' are
> >parentheses, and syntactically the whole thing is a function-call
> >exression.
> > The only sense in which function-call operators exist is
> >semantic, in which case the term refers to the function that will be
> >executed if the corresponding expression is evaluated. Using an operator
> >in that sense refers to the execution of the function, not the writing
> >down of the expression. Since the function-call expression occurs inside
> >the sizeof() expression, it never gets evaluated, and therefore the
> >corresponding function-call operator is not used. That distinction is
> >crucial to my argument.
I only have fragmented bits of your discussion, so please let me paraphrase.
You say that in the expression sizeof( f() ), f() is not actually called so
this
expression does not use f's "function-call operator" and f() is therefore
acceptable in this constant expression.
Since sizeof( f() ) doesn't USE a function-call operator, then I assume
that
int i;
sizeof( typeid( i ) );
isn't a USE of the typeid operator. Therefore the following part
of the Standard is inapplicable in this case:
5.2.8 p6
"If the header <typeinfo> (18.5.1) is not included prior to a use of typeid,
the program is ill-formed."
In sizeof( typeid( i )), the typeid operator is merely written down and
not used (evaluated), just like f in sizeof( f() ). Consequently including
typeinfo.h is not required to compute sizeof( typeid( i ) ).
Could it be that I am wrong and that typeinfo.h is still required in this
case? Like Bill Clinton would say, it depends on what your definition of
"use" is.
---
[ 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.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: "Anon" <spamme@lots.moderated.news.pipex.net>
Date: Mon, 26 Feb 2001 23:00:46 GMT Raw View
Deja User <gennaro_prota@my-deja.com> wrote in message
news:200102221902.LAA28904@mail13.bigmailbox.com...
> On Thu, 22 Feb 2001 13:08:13 GMT, "James Kuyper Jr." <kuyper@wizard.net>
wrote:
>
> int f();
> int array[sizeof(f())];
>
> I agree with you that there's no reason why it should be illegal.
> Now, I know that it is NOT illegal.
Out of curiosity, what if there are multiple f's?
int f( int );
float f( float );
Then which of the following are legal?
1. int array[sizeof(f)];
2. int array[sizeof(f(int))];
3. int i; int array[sizeof(f(i))];
4. int array[sizeof(static_cast<(int*)(int)>(f))];
My belief is that 1 is ambiguous and the others are
all legal, but I'm interested in the experts' opinions.
I think the standard should be changed to make this
sort of thing illegal. Writing sizeof(f()) is confusing
and it can easily be mistaken as an actual call to f
being made with its side-effects.
I think C++ is already sufficiently confusing with all
of its inconsistencies. If you really need to do something
like this, then I suggesting introducing a new operator and
doing something like:
sizeof( result_type<f> )
Then you could also do the following:
result_type<f> i;
---
[ 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.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: Tue, 27 Feb 2001 02:45:56 GMT Raw View
Anon wrote:
...
> I only have fragmented bits of your discussion, so please let me paraphrase.
I'm curious - how did it get fragmented?
> You say that in the expression sizeof( f() ), f() is not actually called so
> this
> expression does not use f's "function-call operator" and f() is therefore
> acceptable in this constant expression.
That's a correct paraphrase.
> Since sizeof( f() ) doesn't USE a function-call operator, then I assume
> that
>
> int i;
> sizeof( typeid( i ) );
>
> isn't a USE of the typeid operator. Therefore the following part
> of the Standard is inapplicable in this case:
>
> 5.2.8 p6
> "If the header <typeinfo> (18.5.1) is not included prior to a use of typeid,
> the program is ill-formed."
As I tried to make clear, I'm not sure my interpretation was the
intended one. My best guess is that the standard's use of the word "use"
in these two different contexts is inconsistent. I could be mistaken.
I'm virtually certain that such code, without <typeinfo>, should be
ill-formed. I also believe, with less certainty, that sizeof(f()) should
be legal.
---
[ 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.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: "Anon" <spamme@lots.UCAR.EDU>
Date: Wed, 28 Feb 2001 00:24:21 GMT Raw View
James Kuyper Jr. <kuyper@wizard.net> wrote in message
news:3A9B04D3.27F5F767@wizard.net...
> Anon wrote:
>
> Anyone unfamiliar with the fact that sizeof(expression) does NOT
> evaluate the expression, isn't ready yet to be paid real money for
> writing C/C++ code.
>
If sizeof(expression) doesn't evaluate the expression, as you claim,
then please explain how sizeof( 2 + 1.0 ) produces the same result
as sizeof( double ).
Regardless of the details, I still consider it offensive that sizeof(f())
does
not evaluate f(). IMHO an expression shouldn't escape evaluation just
because it happens to be embedded in a sizeof statement. Are you
comfortable with monstrosities such as these?
sizeof (1 / 0);
sizeof sqrt( -1 );
sizeof acos( 2 );
sizeof new int[std::numeric_limits<int>::max()];
sizeof delete &std::nothrow;
If you really want to obtain the return type of a function without
evaluating it then there should be an operator for that unrelated to
sizeof.
---
[ 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.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: Salters <salters@lucent.com>
Date: Wed, 28 Feb 2001 10:59:43 CST Raw View
Anon wrote:
> James Kuyper Jr. <kuyper@wizard.net> wrote in message
> news:3A9B04D3.27F5F767@wizard.net...
> > Anon wrote:
> > Anyone unfamiliar with the fact that sizeof(expression) does NOT
> > evaluate the expression, isn't ready yet to be paid real money for
> > writing C/C++ code.
> If sizeof(expression) doesn't evaluate the expression, as you claim,
> then please explain how sizeof( 2 + 1.0 ) produces the same result
> as sizeof( double ).
Ok.
It works like this:
The compiler sees sizeof( . It knows an expression or a type follows.
It then sees 2. Since no type starts with 2, it knows an expression
follows. The expression turns out to be 2+1.0. The compiler needs
the type of this (and nothing more than that!) so it parses the expression.
It turns out the expression is " double operator+(int, double) called
on arguments 1.0 (after conversion) and 2.0". The type of expression
is double, so sizeof(expression) == sizeof(double). And we know that
because of the return type of operator+.
> Regardless of the details, I still consider it offensive that sizeof(f())
> does
> not evaluate f(). IMHO an expression shouldn't escape evaluation just
> because it happens to be embedded in a sizeof statement. Are you
> comfortable with monstrosities such as these?
> sizeof (1 / 0);
> sizeof sqrt( -1 );
> sizeof acos( 2 );
> sizeof new int[std::numeric_limits<int>::max()];
> sizeof delete &std::nothrow;
4/5. The last one is invoking undefined behavior, I think (std::nothrow
is of type std::nothrow_t, which may have an operator& which doesn't
return a T*. )
As to the rest of them, no problem.
--
Michiel Salters
Michiel.Salters@cmg.nl
salters@lucent.com
---
[ 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.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: Wed, 28 Feb 2001 11:16:12 CST Raw View
Anon wrote:
>
> James Kuyper Jr. <kuyper@wizard.net> wrote in message
> news:3A9B04D3.27F5F767@wizard.net...
> > Anon wrote:
> >
> > Anyone unfamiliar with the fact that sizeof(expression) does NOT
> > evaluate the expression, isn't ready yet to be paid real money for
> > writing C/C++ code.
> >
> If sizeof(expression) doesn't evaluate the expression, as you claim,
> then please explain how sizeof( 2 + 1.0 ) produces the same result
> as sizeof( double ).
Section 5.3.3p1 of the C++ standard says quite clearly that
"the operand ... is not evaluated". That's what it says in the C99
standard too. I don't how long that's been the case - I don't have a
copy of the C90 standard, but I believe it's in agreement with C99 on
this issue. However, I just looked at my first edition K&R, and was
surprised to find that there's no explicit statement that the operand is
not evaluated; well, one of the reasons for the original standard was
that K&R left many important details unspecified.
How does it work without evaluating the expression? Very simple - as
it's name implies, evaluation of an expression is the process of
determining the expression's value. Since sizeof() makes absolutely no
use of the expression's value, there's no problem associated with not
evaluating it. What sizeof does need is the type of the expression. The
type is determined entirely by the rules of the C++ language; there's no
need to determine the value of an expression, in order to be able to
determine it's type.
> Regardless of the details, I still consider it offensive that sizeof(f())
> does
> not evaluate f(). ...
You've got to be joking - right? Can you give a single useful example of
code that would be improved by changing the rules to make sizeof() waste
the time needed to evaluate it's enclosed expression? Keep in mind that
sizeof() makes absolutely no use of the value of that expression. Do you
expect sizeof(i++) to increment i?
> ... IMHO an expression shouldn't escape evaluation just
> because it happens to be embedded in a sizeof statement. Are you
You make the function sound like a laborer shirking work. :-)
> comfortable with monstrosities such as these?
>
> sizeof (1 / 0);
> sizeof sqrt( -1 );
> sizeof acos( 2 );
> sizeof new int[std::numeric_limits<int>::max()];
> sizeof delete &std::nothrow;
Yes, I'm comfortable with those expressions. I can't imagine any reason
to write them, but I see little point in prohibiting them, either.
> If you really want to obtain the return type of a function without
> evaluating it then there should be an operator for that unrelated to
> sizeof.
I don't use sizeof() when I want to find the type of an expression, I
use sizeof when I wish to find the size of an object of that type. I use
fancy tricks with templates when I want to find the type of an
expression. I'd prefer to use typeof() for that purpose, but I try to
avoid using non-standard extensions, and it's usually possible to do so.
---
[ 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.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: christian.bau@isltd.insignia.com (Christian Bau)
Date: Wed, 28 Feb 2001 13:14:36 CST Raw View
In article <3a9c3f67$1_2@news.nwlink.com>, "Anon" <spamme@lots.UCAR.EDU> wrote:
> James Kuyper Jr. <kuyper@wizard.net> wrote in message
> news:3A9B04D3.27F5F767@wizard.net...
> > Anon wrote:
> >
> > Anyone unfamiliar with the fact that sizeof(expression) does NOT
> > evaluate the expression, isn't ready yet to be paid real money for
> > writing C/C++ code.
> >
> If sizeof(expression) doesn't evaluate the expression, as you claim,
> then please explain how sizeof( 2 + 1.0 ) produces the same result
> as sizeof( double ).
>
> Regardless of the details, I still consider it offensive that sizeof(f())
> does
> not evaluate f(). IMHO an expression shouldn't escape evaluation just
> because it happens to be embedded in a sizeof statement. Are you
> comfortable with monstrosities such as these?
>
> sizeof (1 / 0);
> sizeof sqrt( -1 );
> sizeof acos( 2 );
> sizeof new int[std::numeric_limits<int>::max()];
> sizeof delete &std::nothrow;
The result of sizeof (expression) answers the question: "If I would
evaluate the expression, what would be the size of the result in bytes? ".
It seems obvious to me that you want to know the answer of your question
_without_ evaluating the expression.
---
[ 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.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: "Ken Hagan" <K.Hagan@thermoteknix.co.uk>
Date: Wed, 28 Feb 2001 19:18:23 GMT Raw View
"Anon" <spamme@lots.UCAR.EDU> wrote...
>
> If sizeof(expression) doesn't evaluate the expression, as you claim,
> then please explain how sizeof( 2 + 1.0 ) produces the same result
> as sizeof( double ).
Easy. The expression "2+1.0" is of type double. You don't need to
evaluate it to know that. It's defined by the syntax. Indeed, actually
evaluating the expression doesn't help, since the precise value doesn't
affect the type at all.
> Are you comfortable with monstrosities such as these?
>
> sizeof (1 / 0);
> sizeof sqrt( -1 );
> sizeof acos( 2 );
> sizeof new int[std::numeric_limits<int>::max()];
> sizeof delete &std::nothrow;
No. I'd reject them in a code review, and even if my compiler didn't
complain, I'd expect a tool like LINT to do so.
The form "sizeof expression" is occasionally useful in situations
where "sizeof type" can't be written because you don't know the
type. (Macros and templates spring to mind, the former being
appropriate in C and the latter in C++.)
> If you really want to obtain the return type of a function without
> evaluating it then there should be an operator for that unrelated to
> sizeof.
Yes, there should be a typeof operator, but that's for another thread.
---
[ 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.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: clarkcox3@yahoo.com (Clark S. Cox, III)
Date: Wed, 28 Feb 2001 19:20:36 GMT Raw View
Anon <spamme@lots.UCAR.EDU> wrote:
> James Kuyper Jr. <kuyper@wizard.net> wrote in message
> news:3A9B04D3.27F5F767@wizard.net...
> > Anon wrote:
> >
> > Anyone unfamiliar with the fact that sizeof(expression) does NOT
> > evaluate the expression, isn't ready yet to be paid real money for
> > writing C/C++ code.
> >
> IMHO an expression shouldn't escape evaluation just
> because it happens to be embedded in a sizeof statement. Are you
> comfortable with monstrosities such as these?
> sizeof (1 / 0);
sizeof int;
> sizeof sqrt( -1 );
sizeof double;
> sizeof acos( 2 );
sizeof double;
> sizeof new int[std::numeric_limits<int>::max()];
sizeof int*;
> sizeof delete &std::nothrow;
undefined behavior
> If you really want to obtain the return type of a function without
> evaluating it then there should be an operator for that unrelated to
> sizeof.
Why should sizeof evaluate the expression? It only needs to know the
size of the type, not the value of the expression.
--
http://www.whereismyhead.com/clark/
Clark S. Cox, III
clarkcox3@yahoo.com
---
[ 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.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: "Anon" <spamme@lots.UCAR.EDU>
Date: Wed, 28 Feb 2001 22:22:40 GMT Raw View
Clark S. Cox, III <clarkcox3@yahoo.com> wrote in message
news:1epjgsc.1vur0171k9pz04N%clarkcox3@yahoo.com...
> Why should sizeof evaluate the expression? It only needs to know the
> size of the type, not the value of the expression.
Why should 0 * (expression) evaluate the expression?? It only needs to
return
0, not waste time computing the value of the expression!
sizeof not evaluating expressions is just another exception to the general
rule where
expressions written down are always evaluated. Short-circuit boolean
operators
are another example (e.g. "0 && ++i") , but these are actually convenient.
The sizeof exception just makes the language more complicated, without
confering a
significant benefit. If you want sizeof to be fast, then give it an
expression that has no
side effects and can be evaluated at compile-time. If you want sizeof's
argument to
have side effects, however, you shouldn't be precluded from doing so. With
some effort,
I believe I could concoct situations where sizeof's with side-effects would
be useful and
elegant.
If you still insist that sizeof shouldn't waste time computing an
expression, then
please explain what you think about 0 * (expression) evaluating the
expression
as it does under the current rules.
BTW from the point of view of job security, I agree with the exception where
sizeof doesn't evaluate its expression. We should continue making the
language
as arbitrary and complicated as possible to keep all of these C++ newcomers
out of the work force, even if it does slow down our programming efforts
slightly.
---
[ 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.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: "Stephen Howe" <NOSPAMsjhowe@dial.pipex.co.uk>
Date: Thu, 1 Mar 2001 06:42:48 GMT Raw View
"Anon" <spamme@lots.UCAR.EDU> wrote in message
news:3a9d728c_2@news.nwlink.com...
Perhaps it shuld be stated that sizeof() is a compile-time operator and
AFAIK, the only one that is (with the exception of C's VLAs). The compiler
just replaces sizeof(expression) with a number that is the size.
Stephen Howe
---
[ 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.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: Thu, 1 Mar 2001 06:45:29 GMT Raw View
Anon wrote:
>
> Clark S. Cox, III <clarkcox3@yahoo.com> wrote in message
> news:1epjgsc.1vur0171k9pz04N%clarkcox3@yahoo.com...
> > Why should sizeof evaluate the expression? It only needs to know the
> > size of the type, not the value of the expression.
>
> Why should 0 * (expression) evaluate the expression?? It only needs to
> return
> 0, not waste time computing the value of the expression!
Given operator overloads, that time is not necessarily wasted - an
argument that doesn't apply to sizeof, since it can't be overloaded
(what a nightmare that would be!).
However, that's only a side issue. The important difference is that you
have alternatives for the case of multiplication. If you don't want the
expression evaluated, just write '0'. In the case of sizeof, if you DO
want the expression evaluated, you can always use
'expression,sizeof(expression)'. With your proposed change to the rules,
how would I go about determining the size of the value of an arbitrary
expression, without evaluating it?
...
> sizeof not evaluating expressions is just another exception to the general
> rule where
> expressions written down are always evaluated. Short-circuit boolean
> operators
> are another example (e.g. "0 && ++i") , but these are actually convenient.
So is the rule for sizeof. I've never used it in a context where I
wanted the side-effect to occur, and I can't imagine how such a context
could come up.
> I believe I could concoct situations where sizeof's with side-effects would
> be useful and
> elegant.
Please try; I'd be very surprised to see and example.
...
> BTW from the point of view of job security, I agree with the exception where
> sizeof doesn't evaluate its expression. We should continue making the
> language
> as arbitrary and complicated as possible to keep all of these C++ newcomers
> out of the work force, even if it does slow down our programming efforts
> slightly.
There's nothing in the least bit arbitrary about this decision. sizeof
was created to fill a need. That need doesn't require evaluation of the
expression, and therefore it would be a waste of time to require
evaluation of the expression.
---
[ 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.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: qrczak@knm.org.pl (Marcin 'Qrczak' Kowalczyk)
Date: Thu, 1 Mar 2001 18:16:44 GMT Raw View
Wed, 28 Feb 2001 22:22:40 GMT, Anon <spamme@lots.UCAR.EDU> pisze:
> Why should 0 * (expression) evaluate the expression??
Would (expr1) * (expr2) evaluate expr2 when expr1 evaluates to 0
but is not a constant 0?
If yes, then the behavior for a constant should be an instance of
the behavior for non-constant of the same value.
If no, then implementations can't evaluate operands of * in arbitrary
order and just use a machine instruction for the multiplication, but
make an explicit test and branch, which usually slows down the code.
You can always write explicit test if you want to skip evaluation of
expr2 in case expr1 is 0.
In any case, (expr1) * (expr2) should always evaluate both expressions.
> sizeof not evaluating expressions is just another exception
> to the general rule where expressions written down are always
> evaluated. Short-circuit boolean operators are another example
> (e.g. "0 && ++i") , but these are actually convenient.
So you admit that the rule doesn't hold anyway.
--=20
__("< Marcin Kowalczyk * qrczak@knm.org.pl http://qrczak.ids.net.pl/
\__/
^^ SYGNATURA ZAST=CAPCZA
QRCZAK
---
[ 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.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: christian.bau@isltd.insignia.com (Christian Bau)
Date: Thu, 1 Mar 2001 18:37:25 GMT Raw View
In article <3a9d728c_2@news.nwlink.com>, "Anon" <spamme@lots.UCAR.EDU> wrote:
> Clark S. Cox, III <clarkcox3@yahoo.com> wrote in message
> news:1epjgsc.1vur0171k9pz04N%clarkcox3@yahoo.com...
> > Why should sizeof evaluate the expression? It only needs to know the
> > size of the type, not the value of the expression.
>
> Why should 0 * (expression) evaluate the expression?? It only needs to
> return
> 0, not waste time computing the value of the expression!
I would say that you are trying to be a sophist, and that you haven't read
or understood the IEEE 754 Standard.
(Explanation: A sophist is someone trying to get the upper hand through
clever but not necessarily correct arguments. )
---
[ 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.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: clarkcox3@yahoo.com (Clark S. Cox, III)
Date: Thu, 1 Mar 2001 21:21:59 GMT Raw View
Marcin 'Qrczak' Kowalczyk <qrczak@knm.org.pl> wrote:
> Wed, 28 Feb 2001 22:22:40 GMT, Anon <spamme@lots.UCAR.EDU> pisze:
>
> > Why should 0 * (expression) evaluate the expression??
>
> Would (expr1) * (expr2) evaluate expr2 when expr1 evaluates to 0
> but is not a constant 0?
In some situations, yes, in some others, no.
> If yes, then the behavior for a constant should be an instance of
> the behavior for non-constant of the same value.
>
> If no, then implementations can't evaluate operands of * in arbitrary
> order and just use a machine instruction for the multiplication, but
> make an explicit test and branch, which usually slows down the code.
>
> You can always write explicit test if you want to skip evaluation of
> expr2 in case expr1 is 0.
>
> In any case, (expr1) * (expr2) should always evaluate both expressions.
No, if one of the expressions evaluates to zero, and the other has
no side effects, a compiler is free to omit the evaluation of the other
expression.
> > sizeof not evaluating expressions is just another exception
> > to the general rule where expressions written down are always
> > evaluated. Short-circuit boolean operators are another example
> > (e.g. "0 && ++i") , but these are actually convenient.
>
> So you admit that the rule doesn't hold anyway.
--
http://www.whereismyhead.com/clark/
Clark S. Cox, III
clarkcox3@yahoo.com
---
[ 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.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: clarkcox3@yahoo.com (Clark S. Cox, III)
Date: Thu, 1 Mar 2001 21:22:24 GMT Raw View
Marcin 'Qrczak' Kowalczyk <qrczak@knm.org.pl> wrote:
> Wed, 28 Feb 2001 22:22:40 GMT, Anon <spamme@lots.UCAR.EDU> pisze:
>
> > Why should 0 * (expression) evaluate the expression??
>
> Would (expr1) * (expr2) evaluate expr2 when expr1 evaluates to 0
> but is not a constant 0?
>
> If yes, then the behavior for a constant should be an instance of
> the behavior for non-constant of the same value.
>
> If no, then implementations can't evaluate operands of * in arbitrary
> order and just use a machine instruction for the multiplication, but
> make an explicit test and branch, which usually slows down the code.
>
> You can always write explicit test if you want to skip evaluation of
> expr2 in case expr1 is 0.
>
> In any case, (expr1) * (expr2) should always evaluate both expressions.
Sorry for the double post, but I thought that I'd give some examples:
On my compiler:
int foo()
{
int x = 0;
return x * 5;
}
Compiles to (PowerPC Assembly):
li r3,0
blr
Which obviously doesn't do any multiplication. It simply sets
register 3 to zero, and returns to the caller. I'd be willing to bet
that many other compilers will do the same optimization.
--
http://www.whereismyhead.com/clark/
Clark S. Cox, III
clarkcox3@yahoo.com
---
[ 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.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: "Ken Hagan" <K.Hagan@thermoteknix.co.uk>
Date: Fri, 2 Mar 2001 00:04:35 GMT Raw View
"Anon" <spamme@lots.UCAR.EDU> wrote...
>
> sizeof not evaluating expressions is just another exception to the
> general rule where expressions written down are always evaluated.
> Short-circuit boolean operators are another example (e.g. "0 && ++i"),
> but these are actually convenient.
As is the behaviour of sizeof. Because it doesn't evaluate the
expression, it can be used as a compile-time constant. That is
at least as convenient as the short-circuit evaluation rule.
---
[ 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.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: qrczak@knm.org.pl (Marcin 'Qrczak' Kowalczyk)
Date: Sun, 4 Mar 2001 04:12:33 GMT Raw View
Thu, 1 Mar 2001 21:21:59 GMT, Clark S. Cox, III <clarkcox3@yahoo.com> pi=
sze:
> > In any case, (expr1) * (expr2) should always evaluate both expression=
s.
>=20
> No, if one of the expressions evaluates to zero, and the other has
> no side effects, a compiler is free to omit the evaluation of the other
> expression.
In this case no program can tell the difference, so obviously the
compiler can compile in any way it wants. We are talking about the
meaning of a program, not about the way it can be compiled, i.e. about
cases when it does make a difference.
--=20
__("< Marcin Kowalczyk * qrczak@knm.org.pl http://qrczak.ids.net.pl/
\__/
^^ SYGNATURA ZAST=CAPCZA
QRCZAK
---
[ 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.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: "Deja User" <gennaro_prota@my-deja.com>
Date: Sun, 4 Mar 2001 18:21:41 GMT Raw View
On Tue, 27 Feb 2001 19:01:57 GMT, bill@gibbons.org (Bill Gibbons) wrote:
>The word "use" is certainly overused in the standard. There are two distinct
>meanings for "using" a type or declared entity:
>
> (1) The type, or one or more declaration attributes (such as type) of a
> declared entity, is used for the purpose of determining the validity
> and semantics of the program.
>
> (2) The declared entity could potentially be referenced during program
> execution.
>
>The typeid case is unusual because the type in question (std::type_info)
>is not mentioned explicitly. But since the validity of the expression
>"typeid(i)" in its context depends on the meaning of "std:type_info",
>this is a "use" of "std::type_info" in the first sense. This implies
>that the meaning of "use" in 5.2.8p6 is the first meaning, and that
>the header must be included in the example.
>
>In general (1) is the "use" of a declaration or class definition and
>(2) is the "use" of a function or object definition, but there are
>exceptions to this rule. For example, the definition of a compile-time
>constant (e.g. "const int x = 3;") may be "used" in the first sense
>as in "int array[x];", or in the both senses as in "int y = x;".
>
>Here is an even more obscure example:
>
> template<int *p> class A { };
> extern int x;
> A<&x> a;
>
>Even though "x" appears to have its address taken, it isn't "used" in
>the second sense. The special case of a nontype template argument
>which is a pointer or reference is a declarative use only; as long as
>the corresponding template parameter ("p" above) is not "used" in the
>second sense in an instantiation of the template, the template argument
>itself ("&x" above) is not "used" in the second sense.
>
>As a result, the global object "x" need not be defined anywhere in the
>program.
>
I cannot believe this is a correct interpretation. Maybe I didn't understand your reasoning...but is sounds quite odd.
When you write sizeof (f()) the type of the function f MUST be used in the first sense (the entire sizeof expression could be illegal if, for instance, f was declared as void).
The same happens if you write:
const int n = 5;
std::size_t s = sizeof(n); // n is "used" in the first sense
or
A a;
std::size_t s = sizeof(a);
Now, unless you think that the last example is illegal ( :-) ), it seems that the standard prohibits, for functions, class objects, pointers, or references, their "use" in the second sense, if expressions that designate them (NOTE the difference between an entity and the expression that designates it) appear in a sizeof expression.
But this means that
sizeof (f())
is legal only if f is never called in other parts of the program, so that the validity of the expression depends on the rest of the source code. (Analogously of sizeof(a): legal only if a is never referenced elsewhere!)
I came to this conclusion reading what you say about template example you supplied, where you talk about "referencing" the same entity through different expressions (p and &x).
Gennaro Prota.
------------------------------------------------------------
--== Sent via Deja.com ==--
http://www.deja.com/
---
[ 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.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]