Topic: static_cast<const unsigned int&>(lvalue-of-type-int)


Author: anthony.williamsNOSPAM@anthonyw.cjb.net (Anthony Williams)
Date: Wed, 28 May 2003 16:41:05 +0000 (UTC)
Raw View
jpotter@falcon.lhup.edu (John Potter) writes:

> On Tue, 27 May 2003 17:25:48 +0000 (UTC), ron@sensor.com ("Ron Natalie")
> wrote:
>
> > "John Potter" <jpotter@falcon.lhup.edu> wrote in message
> > news:t07tcvgmo6lqchevfoplcs7fa8p84fle9r@4ax.com...
>
> > > #2 changes an lvalue of type int to an lvalue of type unsigned int.
> > > That is the job of reinterpret_cast not static cast.  Where do you
> > > find otherwise?
>
> > Try reading 5.2.9.  static_cast doesn't have the behavior you describe
> > (neither does reinterpret_cast for that matter).  It changes nothing to an
> > "lvalue".  It just happens that if the type is a reference, the result IS
> > an lvalue.
>
> You start with an lvalue of type int and end with an lvalue of type
> unsigned const int.  It changes the type of an lvalue.

No, it creates a *new* lvalue which refers to the temporary object created.

> > Read the second paragraph now...
>
> > An expression e can be explicitly converted to a type T using a
> > static_cast of the form static_cast<T>(e) if the declaration "T t(e);" is
> > well-formed, for some invented temporary vari-able t (8.5). The effect of
> > such an explicit conversion is the same as performing the declaration and
> > initial-ization and then using the temporary variable as the result of the
> > conversion. The result is an lvalue if T is a reference type (8.3.2), and
> > an rvalue otherwise.  The expression e is used as an lvalue if and only if
> > the initialization uses it as an lvalue.
>
> > Tell me how this allows case #2 to differ in behavior from case #1?
>
> Word games?  Variables name objects.  References are not objects.  There
> can be no invented temporary variable t of type unsigned int const&.  The
> second paragraph does not apply nor does any other.

In which case:

int i;
static_cast<int&>(i);

is also ill-formed, because there is no paragraph that allows it other than
5.2.9p2, aside from the general 5.2.9p1 which describes the intent of
static_cast --- I don't see that this paragraph can actually be used as a
basis for allowing/disallowing anything, since it doesn't say what mechanism
is to be used for the conversion.

The only other potential candidate that I can see is 5.2.9p8, which
allows for the reverse of a standard conversion, other than lvalue-to-rvalue
conversions (and others), and the only standard conversion that I can see
listed that could apply for converting an int& to an int is the
lvalue-to-rvalue conversion, which cannot be reversed.

I hope you agree that this would be a poor state of affairs, that consequently
5.2.9p2 should not be interpreted to ban such a non-conversion, and that an
interpretation that allows static_cast<int&>(i) would also allow
static_cast<unsigned const&>(i).

> We then find that this
> case is covered by 5.2.10/10.
>
> If it were allowed, we would have the strange behavior.
>
> (unsigned int&)x is reinterpret_cast<unsigned int&>(x)
> (unsigned int const&)x is static_cast<unsigned int const&>(x)
>
> The first changes the type of an lvalue without introducing anything
> while the second creates a tempory and binds it to a temporary lvalue.
> A rather strange effect for const.

No more strange than the fact that the following is legal:

#include <string>
char h[]="hello";
const std::string& s=h; // huh? h is not a std::string

It is the fact that binding to a const reference can generate a temporary that
is the cause for surprise.

If you want a reinterpret_cast, say so. If you don't say what you want, then
you have to accept what you're given. Yet another reason to "Prefer C++-style
Casts"

Anthony
--
Anthony Williams
Senior Software Engineer, Beran Instruments Ltd.
Remove NOSPAM when replying, for timely response.

---
[ 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: kanze@gabi-soft.fr
Date: Wed, 28 May 2003 16:41:39 +0000 (UTC)
Raw View
jpotter@falcon.lhup.edu (John Potter) wrote in message
news:<6008dv05o504ttalkt7kjsratliln2ssvq@4ax.com>...
> On Tue, 27 May 2003 17:25:48 +0000 (UTC), ron@sensor.com ("Ron
> Natalie") wrote:

> > "John Potter" <jpotter@falcon.lhup.edu> wrote in message
> > news:t07tcvgmo6lqchevfoplcs7fa8p84fle9r@4ax.com...

> > > #2 changes an lvalue of type int to an lvalue of type unsigned
> > > int.  That is the job of reinterpret_cast not static cast.  Where
> > > do you find otherwise?

> > Try reading 5.2.9.  static_cast doesn't have the behavior you
> > describe (neither does reinterpret_cast for that matter).  It
> > changes nothing to an "lvalue".  It just happens that if the type is
> > a reference, the result IS an lvalue.

> You start with an lvalue of type int and end with an lvalue of type
> unsigned const int.  It changes the type of an lvalue.

No, because the lvalue you end up with is a different object than the
one you started with.  This is a fundamental difference between lvalues
and rvalues -- lvalues have identity, rvalues traditionally didn't.

> > Read the second paragraph now...

> > An expression e can be explicitly converted to a type T using a
> > static_cast of the form static_cast<T>(e) if the declaration "T
> > t(e);" is well-formed, for some invented temporary variable t
> > (8.5). The effect of such an explicit conversion is the same as
> > performing the declaration and initialization and then using the
> > temporary variable as the result of the conversion. The result is an
> > lvalue if T is a reference type (8.3.2), and an rvalue otherwise.
> > The expression e is used as an lvalue if and only if the
> > initialization uses it as an lvalue.

> > Tell me how this allows case #2 to differ in behavior from case #1?

> Word games?  Variables name objects.  References are not objects.

But a reference may name an object, even if it isn't an object itself.

> There can be no invented temporary variable t of type unsigned int
> const&.  The second paragraph does not apply nor does any other.  We
> then find that this case is covered by 5.2.10/10.

Are you saying that a variable cannot have a reference type?

> If it were allowed, we would have the strange behavior.

> (unsigned int&)x is reinterpret_cast<unsigned int&>(x)
> (unsigned int const&)x is static_cast<unsigned int const&>(x)

True, but since when is strange behavior a reason for not having
something in the standard?

> The first changes the type of an lvalue without introducing anything
> while the second creates a tempory and binds it to a temporary lvalue.
> A rather strange effect for const.

True.  But it isn't the only strange effect in the standard, not by a
long shot.

--
James Kanze             GABI Software             mailto:kanze@gabi-soft.fr
Conseils en informatique orient   e objet/
                           Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, T   l. : +33 (0)1 30 23 45 16

---
[ 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: Thu, 29 May 2003 04:49:19 +0000 (UTC)
Raw View
On Wed, 28 May 2003 16:41:39 +0000 (UTC), kanze@gabi-soft.fr wrote:

> jpotter@falcon.lhup.edu (John Potter) wrote in message
> news:<6008dv05o504ttalkt7kjsratliln2ssvq@4ax.com>...
> > On Tue, 27 May 2003 17:25:48 +0000 (UTC), ron@sensor.com ("Ron
> > Natalie") wrote:

> > > Try reading 5.2.9.  static_cast doesn't have the behavior you
> > > describe (neither does reinterpret_cast for that matter).  It
> > > changes nothing to an "lvalue".  It just happens that if the type is
> > > a reference, the result IS an lvalue.

> > You start with an lvalue of type int and end with an lvalue of type
> > unsigned const int.  It changes the type of an lvalue.

> No, because the lvalue you end up with is a different object than the
> one you started with.  This is a fundamental difference between lvalues
> and rvalues -- lvalues have identity, rvalues traditionally didn't.

Agreed.  The statement is correct for reinterpret_cast which does not
create anything new.

> > Word games?  Variables name objects.  References are not objects.

> But a reference may name an object, even if it isn't an object itself.

> > There can be no invented temporary variable t of type unsigned int
> > const&.  The second paragraph does not apply nor does any other.  We
> > then find that this case is covered by 5.2.10/10.

> Are you saying that a variable cannot have a reference type?

Yes.  However, 8.5.3/1 proves me wrong.

Can you explain why every major compiler rejects the static_cast?
Would it create two temporaries?  Is a temporary reference possible?
What covers the lifetime of temporary references?  Can references be
created?  Note that no other feference cast produces anything.  The
reference refers to an lvalue which already existed.

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: jpotter@falcon.lhup.edu (John Potter)
Date: Thu, 29 May 2003 04:49:25 +0000 (UTC)
Raw View
On Wed, 28 May 2003 16:41:05 +0000 (UTC),
anthony.williamsNOSPAM@anthonyw.cjb.net (Anthony Williams) wrote:

> jpotter@falcon.lhup.edu (John Potter) writes:
>
> > On Tue, 27 May 2003 17:25:48 +0000 (UTC), ron@sensor.com ("Ron Natalie")
> > wrote:

> > > Try reading 5.2.9.  static_cast doesn't have the behavior you describe
> > > (neither does reinterpret_cast for that matter).  It changes nothing to an
> > > "lvalue".  It just happens that if the type is a reference, the result IS
> > > an lvalue.

> > You start with an lvalue of type int and end with an lvalue of type
> > unsigned const int.  It changes the type of an lvalue.

> No, it creates a *new* lvalue which refers to the temporary object created.

I seem to have left out reinterpret_cast.  It changes the type of an
lvalue.  Static_cast creates a new lvalue?

> > Word games?  Variables name objects.  References are not objects.  There
> > can be no invented temporary variable t of type unsigned int const&.  The
> > second paragraph does not apply nor does any other.

> In which case:

> int i;
> static_cast<int&>(i);

Does this create a temporary?

> is also ill-formed,

Yes, and other problems.  /5 allows a reference down cast.  Note that the
reference upcast is not a standard conversion and is not covered by the
general inverse rule.  Without /2 no standard conversion is covered.

> I hope you agree that this would be a poor state of affairs, that consequently
> 5.2.9p2 should not be interpreted to ban such a non-conversion, and that an
> interpretation that allows static_cast<int&>(i) would also allow
> static_cast<unsigned const&>(i).

Agreed.  Now explain why every major compiler rejects the static_cast.  I
tried but am obviously wrong.  Why did gnu correct a bug that accepted it?

> > If it were allowed, we would have the strange behavior.

> > (unsigned int&)x is reinterpret_cast<unsigned int&>(x)
> > (unsigned int const&)x is static_cast<unsigned int const&>(x)

> > The first changes the type of an lvalue without introducing anything
> > while the second creates a tempory and binds it to a temporary lvalue.
> > A rather strange effect for const.

> No more strange than the fact that the following is legal:

> #include <string>
> char h[]="hello";
> const std::string& s=h; // huh? h is not a std::string

That is not a surprise because it is well stated in the standard.

> It is the fact that binding to a const reference can generate a temporary that
> is the cause for surprise.

No.  The surprise is that the wording seems to allow static_cast to create
two temporaries and that every major compiler forbids it.

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: gdr@integrable-solutions.net (Gabriel Dos Reis)
Date: Thu, 29 May 2003 15:53:00 +0000 (UTC)
Raw View
jpotter@falcon.lhup.edu (John Potter) writes:

| On Wed, 28 May 2003 16:41:05 +0000 (UTC),
| anthony.williamsNOSPAM@anthonyw.cjb.net (Anthony Williams) wrote:
|
| > jpotter@falcon.lhup.edu (John Potter) writes:
| >
| > > On Tue, 27 May 2003 17:25:48 +0000 (UTC), ron@sensor.com ("Ron Natalie")
| > > wrote:
|
| > > > Try reading 5.2.9.  static_cast doesn't have the behavior you describe
| > > > (neither does reinterpret_cast for that matter).  It changes nothing to an
| > > > "lvalue".  It just happens that if the type is a reference, the result IS
| > > > an lvalue.
|
| > > You start with an lvalue of type int and end with an lvalue of type
| > > unsigned const int.  It changes the type of an lvalue.
|
| > No, it creates a *new* lvalue which refers to the temporary object created.
|
| I seem to have left out reinterpret_cast.  It changes the type of an
| lvalue.  Static_cast creates a new lvalue?

Generally, static cast creates an rvalue unless the target type is of
reference type.  In that case, if the referred to type and the source
type are not related, then static_cast create a temporary and bind the
reference to it assuming the reference is const; or else the program
is ill-formed.

[...]

| Agreed.  Now explain why every major compiler rejects the  static_cast.

A bug.  I do recall we already had this discussion here or on
comp.lang.c++.moderated.

(interestingly, it seems that compilers now have started being
bug-compatbile.  XXX will have the same bug as YYY with the excuse
"we want to behave the same as YYY because it is well respected.  YYY
will have the same bug as XXX because it wants to compile the same
things as XXX. Which, of course, brings the vicious cirle)

| I
| tried but am obviously wrong.  Why did gnu correct a bug that accepted it?

I do not believe that was a "correction" on purpose.  Previously, GCC
accepted the code but did the WRONG thing with it (it did a
reinterpret_cast).  Historically, GCC seems to have problems with the
less "obvious" constructs with the new style casts.

--
Gabriel Dos Reis, gdr@integrable-solutions.net

---
[ 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: gdr@integrable-solutions.net (Gabriel Dos Reis)
Date: Thu, 29 May 2003 15:53:06 +0000 (UTC)
Raw View
jpotter@falcon.lhup.edu (John Potter) writes:

[...]

| Can you explain why every major compiler rejects the static_cast?

Compiler bug.

| Would it create two temporaries?

One.

| Is a temporary reference possible?
| What covers the lifetime of temporary references?  Can references be
| created?

The same as in

  const T& tmp(value);

--
Gabriel Dos Reis, gdr@integrable-solutions.net

---
[ 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: Thu, 29 May 2003 18:05:51 +0000 (UTC)
Raw View
On Thu, 29 May 2003 15:53:06 +0000 (UTC), gdr@integrable-solutions.net
(Gabriel Dos Reis) wrote:

> jpotter@falcon.lhup.edu (John Potter) writes:

> | Can you explain why every major compiler rejects the static_cast?

> Compiler bug.

Bug compatible.

> | Would it create two temporaries?

> One.

Hum.  Then where is the reference that is bound to the rvalue?  That
invented variable of type int& that is returned by the cast.

> | Is a temporary reference possible?
> | What covers the lifetime of temporary references?  Can references be
> | created?

> The same as in

>   const T& tmp(value);

That reference is not temporary.

void f (unsigned int x) {
   int const& cr1(x); // valid to end of function
   int const& cr2(static_cast<int>(x)); // ditto
   int& r1(const_cast<int&>(
         static_cast<int const&>(
         static_cast<int>(x)))); // dangling reference
   int const& cr3(static_cast<int const&>(static_cast<int>(x)));// ditto
   int const& cr4(static_cast<int const&>(x)); // ditto if valid
   int& r2(*static_cast<int*>(static_cast<void*>(&x))); // reinterpret
   int& r3(reinterpret_cast<int&>(x)); // ditto
   }

FWIW, gcc-3.2 agrees.  In particular, it does create a temporary and
destroy it immediately in the questioned cr4.  It does not
reinterpret_cast in that statement.  Using two or more casts as in r1,
cr3, and r2 is asking for trouble.  It seems that cr4 is as bad.

By reading the standard, we conclude that the expression is valid and
useless.  By observing the compilers, we conclude that the expression
is invalid and useless.  I still wonder if the compiler writers do not
see something that we are missing.  Since it is useless in any case, I
guess it is also uninteresting.

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: gdr@integrable-solutions.net (Gabriel Dos Reis)
Date: Thu, 29 May 2003 18:34:30 +0000 (UTC)
Raw View
jpotter@falcon.lhup.edu (John Potter) writes:

[...]

| > | Is a temporary reference possible?
| > | What covers the lifetime of temporary references?  Can references be
| > | created?
|
| > The same as in
|
| >   const T& tmp(value);
|
| That reference is not temporary.
|
| void f (unsigned int x) {
|    int const& cr1(x); // valid to end of function
|    int const& cr2(static_cast<int>(x)); // ditto
|    int& r1(const_cast<int&>(
|          static_cast<int const&>(
|          static_cast<int>(x)))); // dangling reference

Agreed.

|    int const& cr3(static_cast<int const&>(static_cast<int>(x)));// ditto

Agreed.

|    int const& cr4(static_cast<int const&>(x)); // ditto if valid
|    int& r2(*static_cast<int*>(static_cast<void*>(&x))); // reinterpret
|    int& r3(reinterpret_cast<int&>(x)); // ditto
|    }
|
| FWIW, gcc-3.2 agrees.  In particular, it does create a temporary and
| destroy it immediately in the questioned cr4.  It does not
| reinterpret_cast in that statement.  Using two or more casts as in r1,
| cr3, and r2 is asking for trouble.  It seems that cr4 is as bad.

cr4 is probaly not a good idea.  But that does not, by itself,
demonstrate  that the semantics described is useless.  You cannot deem
a construct as being useless just by an XYZ example.

--
Gabriel Dos Reis, gdr@integrable-solutions.net

---
[ 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: jsa@edg.com (J. Stephen Adamczyk)
Date: Fri, 30 May 2003 20:01:12 +0000 (UTC)
Raw View
noway@sorry.com ("Giovanni Bajo") wrote in message news:<Julza.25174$lK4.745407@twister1.libero.it>...
> ------------------------------------------------
> void foo(int x)
> {
>     const unsigned int& y = x;  // #1
>     static_cast<const unsigned int&>(x);  // #2
> }
>
> ------------------------------------------------
>
> Is the above code legal? #1 is obviously legal, the problem is with #2. Most
> compilers (including Comeau/EDG and GCC) accept #1 but not #2. But shouldn't
> #2 be valid any time that #1 is valid (by the definition of static_cast in
>    5.2.9/2)? MSVC71 compiles the code.

This is a bug in Comeau/EDG.  We should accept #2 as well.

Steve Adamczyk
Edison Design Group

---
[ 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: apurva@gmx.net (Apurva Mehta)
Date: Tue, 27 May 2003 17:20:23 +0000 (UTC)
Raw View
On Sun, 25 May 2003 14:18:32 +0000 (UTC)
jpotter@falcon.lhup.edu (John Potter) wrote:

> void foo(int x)
> {
>     const unsigned int& y = x;  // #1
>     static_cast<const unsigned int&>(x);  // #2
> }
>
> #2 changes an lvalue of type int to an lvalue of type unsigned int.
> That is the job of reinterpret_cast not static cast.  Where do you
> find otherwise?

No,  #2 does not do that. static_cast is a template function which
takes the value to be casted as an argument and the type to be casted
to as a template parameter. One possible declaration of static_cast is
as follows :

template<class T, class U>
T static_cast (U x) ;

As you can see, static_cast does not modify the the passed argument in
any way, it just returns the argument casted to the type specified by
T, as long as the cast is allowed.

Another example :

void foo()
{
  char x = 'a';
  int y = static_cast<int>(x);
  cout<<x<<' '<<y<<'\n ';
}

Here x will display 'a' which proves that x itself is not casted to an
int. static_cast returns an int which is casted from x. y will
display 97. In particular, the argument does not need to be an lvalue.
You could have:

int y = static_cast<int>('a');

Also, static_cast only performs casts between related types. IMO, an
int and an unsigned int are related types.

 - Apurva

---
[ 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: anthony.williamsNOSPAM@anthonyw.cjb.net (Anthony Williams)
Date: Tue, 27 May 2003 17:20:54 +0000 (UTC)
Raw View
jpotter@falcon.lhup.edu (John Potter) writes:

> On Fri, 23 May 2003 18:44:21 +0000 (UTC), ron@sensor.com ("Ron Natalie")
> wrote:
>
> > ""Giovanni Bajo"" <noway@sorry.com> wrote in message
> > news:Julza.25174$lK4.745407@twister1.libero.it...
>
> > > Is the above code legal? #1 is obviously legal, the problem is with
> > > #2. Most compilers (including Comeau/EDG and GCC) accept #1 but not #2.
>
> > G++ 3.2.2 accepts both (as it should).
>
> void foo(int x)
> {
>     const unsigned int& y = x;  // #1
>     static_cast<const unsigned int&>(x);  // #2
> }
>
> #1 consturcts an unnamed temporary of type unsigned int initialized
> by x and binds with the const&.  Fine.
>
> #2 changes an lvalue of type int to an lvalue of type unsigned int.
> That is the job of reinterpret_cast not static cast.  Where do you
> find otherwise?

5.2.9p2:

"An expression e can be explicitly converted to a type T using a static_cast
of the form static_cast<T>(e) if the declaration "T t(e);" is well-formed, for
some invented temporary variable t (8.5). The effect of such an explicit
conversion is the same as performing the declaration and initialization and
then using the temporary variable as the result of the conversion. The result
is an lvalue if T is a reference type (8.3.2), and an rvalue otherwise. The
expression e is used as an lvalue if and only if the initialization uses it as
an lvalue."

Consequently, #2 is the same as #1, except that the resulting reference is a
temporary.

Anthony
--
Anthony Williams
Senior Software Engineer, Beran Instruments Ltd.
Remove NOSPAM when replying, for timely response.

---
[ 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: sbeasley@cs.uic.edu (Shane Beasley)
Date: Tue, 27 May 2003 17:24:26 +0000 (UTC)
Raw View
jpotter@falcon.lhup.edu (John Potter) wrote in message news:<t07tcvgmo6lqchevfoplcs7fa8p84fle9r@4ax.com>...

> void foo(int x)
> {
>     const unsigned int& y = x;  // #1
>     static_cast<const unsigned int&>(x);  // #2
> }
>
> #1 consturcts an unnamed temporary of type unsigned int initialized
> by x and binds with the const&.  Fine.
>
> #2 changes an lvalue of type int to an lvalue of type unsigned int.
> That is the job of reinterpret_cast not static cast.  Where do you
> find otherwise?

5.2.9/2 says that static_cast<T>(e) is okay whenever T t(e) is okay.
Making the appropriate substitutions, we get

  const unsigned int &y(x);

which is #1 (which you said is fine) using direct-initialization
syntax.

- Shane

---
[ 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: noway@sorry.com ("Giovanni Bajo")
Date: Tue, 27 May 2003 17:25:41 +0000 (UTC)
Raw View
John Potter wrote:

> void foo(int x)
> {
>     const unsigned int& y = x;  // #1
>     static_cast<const unsigned int&>(x);  // #2
> }

>[...]

> #2 changes an lvalue of type int to an lvalue of type unsigned int.
> That is the job of reinterpret_cast not static cast.  Where do you
> find otherwise?


Well, I guess it should be legal because of:

   5.9.2/2: An expression e can be explicitly converted to a type T using a
static_cast of the form static_cast<T>(e) if the declaration "T t(e);" is
well-formed, for some invented temporary variable t (8.5). The effect of
such an explicit conversion is the same as performing the declaration and
initialization and then using the temporary variable as the result of the
conversion.

--
Giovanni Bajo

---
[ 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: noway@sorry.com ("Giovanni Bajo")
Date: Tue, 27 May 2003 17:25:45 +0000 (UTC)
Raw View
"Ron Natalie" wrote:

>> Is the above code legal? #1 is obviously legal, the problem is with #2.
>> Most
>> compilers (including Comeau/EDG and GCC) accept #1 but not #2.
>
> G++ 3.2.2 accepts both (as it should).

Yes, but G++ 3.3 and pre-3.4 don't anymore. This issue comes from a GCC bug
report, in fact.
--
Giovanni Bajo

---
[ 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: ron@sensor.com ("Ron Natalie")
Date: Tue, 27 May 2003 17:25:48 +0000 (UTC)
Raw View
"John Potter" <jpotter@falcon.lhup.edu> wrote in message news:t07tcvgmo6lqchevfoplcs7fa8p84fle9r@4ax.com...


> #2 changes an lvalue of type int to an lvalue of type unsigned int.
> That is the job of reinterpret_cast not static cast.  Where do you
> find otherwise?

Try reading 5.2.9.   static_cast doesn't have the behavior you describe
(neither does reinterpret_cast for that matter).  It changes nothing to
an "lvalue".   It just happens that if the type is a reference, the result IS
an lvalue.

Read the second paragraph now...

An expression e can be explicitly converted to a type T using a static_cast of the form
static_cast<T>(e) if the declaration "T t(e);" is well-formed, for some invented temporary vari-able
t (8.5). The effect of such an explicit conversion is the same as performing the declaration and initial-ization
and then using the temporary variable as the result of the conversion. The result is an lvalue if T is a
reference type (8.3.2), and an rvalue otherwise. The expression e is used as an lvalue if and only if the
initialization uses it as an lvalue.

Tell me how this allows case #2 to differ in behavior from case #1?



---
[ 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: ron@sensor.com ("Ron Natalie")
Date: Tue, 27 May 2003 17:58:02 +0000 (UTC)
Raw View
"Apurva Mehta" <apurva@gmx.net> wrote in message news:20030527112000.61f69639.apurva@gmx.net...

>
> No,  #2 does not do that. static_cast is a template function which
> takes the value to be casted as an argument and the type to be casted
> to as a template parameter. One possible declaration of static_cast is
> as follows :

Static cast isn't a template at all.   The rest of this post is a fallacy.


---
[ 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: noway@sorry.com ("Giovanni Bajo")
Date: Tue, 27 May 2003 18:26:28 +0000 (UTC)
Raw View
"Ron Natalie" wrote:

> An expression e can be explicitly converted to a type T using a
static_cast
> of the form
> static_cast<T>(e) if the declaration "T t(e);" is well-formed, for some
> invented temporary vari-able
> t (8.5). The effect of such an explicit conversion is the same as
> performing the declaration and initial-ization and then using the
temporary
> variable as the result of the conversion. The result is an lvalue if T is
a
> reference type (8.3.2), and an rvalue otherwise. The expression e is used
> as an lvalue if and only if the initialization uses it as an lvalue.
>
> Tell me how this allows case #2 to differ in behavior from case #1?


There seems to be agreement on this, in fact. I wonder why all major
compilers reject #2. Maybe someone from EDG can clarify on this issue?
--
Giovanni Bajo

---
[ 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: Wed, 28 May 2003 03:52:56 +0000 (UTC)
Raw View
On Tue, 27 May 2003 17:25:48 +0000 (UTC), ron@sensor.com ("Ron Natalie")
wrote:

> "John Potter" <jpotter@falcon.lhup.edu> wrote in message news:t07tcvgmo6lqchevfoplcs7fa8p84fle9r@4ax.com...

> > #2 changes an lvalue of type int to an lvalue of type unsigned int.
> > That is the job of reinterpret_cast not static cast.  Where do you
> > find otherwise?

> Try reading 5.2.9.   static_cast doesn't have the behavior you describe
> (neither does reinterpret_cast for that matter).  It changes nothing to
> an "lvalue".   It just happens that if the type is a reference, the result IS
> an lvalue.

You start with an lvalue of type int and end with an lvalue of type
unsigned const int.  It changes the type of an lvalue.

> Read the second paragraph now...

> An expression e can be explicitly converted to a type T using a static_cast of the form
> static_cast<T>(e) if the declaration "T t(e);" is well-formed, for some invented temporary
> vari-able t (8.5). The effect of such an explicit conversion is the same as performing the
> declaration and initial-ization and then using the temporary variable as the result of the
> conversion. The result is an lvalue if T is a reference type (8.3.2), and an rvalue otherwise.
> The expression e is used as an lvalue if and only if the initialization uses it as an lvalue.

> Tell me how this allows case #2 to differ in behavior from case #1?

Word games?  Variables name objects.  References are not objects.  There
can be no invented temporary variable t of type unsigned int const&.  The
second paragraph does not apply nor does any other.  We then find that this
case is covered by 5.2.10/10.

If it were allowed, we would have the strange behavior.

(unsigned int&)x is reinterpret_cast<unsigned int&>(x)
(unsigned int const&)x is static_cast<unsigned int const&>(x)

The first changes the type of an lvalue without introducing anything
while the second creates a tempory and binds it to a temporary lvalue.
A rather strange effect for const.

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: noway@sorry.com ("Giovanni Bajo")
Date: Fri, 23 May 2003 18:27:52 +0000 (UTC)
Raw View
Hello:

------------------------------------------------
void foo(int x)
{
    const unsigned int& y = x;  // #1
    static_cast<const unsigned int&>(x);  // #2
}

------------------------------------------------

Is the above code legal? #1 is obviously legal, the problem is with #2. Most
compilers (including Comeau/EDG and GCC) accept #1 but not #2. But shouldn't
#2 be valid any time that #1 is valid (by the definition of static_cast in
   5.2.9/2)? MSVC71 compiles the code.

Thanks
--
Giovanni Bajo

---
[ 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: ron@sensor.com ("Ron Natalie")
Date: Fri, 23 May 2003 18:44:21 +0000 (UTC)
Raw View
""Giovanni Bajo"" <noway@sorry.com> wrote in message news:Julza.25174$lK4.745407@twister1.libero.it...

>
> Is the above code legal? #1 is obviously legal, the problem is with #2. Most
> compilers (including Comeau/EDG and GCC) accept #1 but not #2.

G++ 3.2.2 accepts both (as it should).


---
[ 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: Sun, 25 May 2003 14:18:32 +0000 (UTC)
Raw View
On Fri, 23 May 2003 18:44:21 +0000 (UTC), ron@sensor.com ("Ron Natalie")
wrote:

> ""Giovanni Bajo"" <noway@sorry.com> wrote in message news:Julza.25174$lK4.745407@twister1.libero.it...

> > Is the above code legal? #1 is obviously legal, the problem is with #2. Most
> > compilers (including Comeau/EDG and GCC) accept #1 but not #2.

> G++ 3.2.2 accepts both (as it should).

void foo(int x)
{
    const unsigned int& y = x;  // #1
    static_cast<const unsigned int&>(x);  // #2
}

#1 consturcts an unnamed temporary of type unsigned int initialized
by x and binds with the const&.  Fine.

#2 changes an lvalue of type int to an lvalue of type unsigned int.
That is the job of reinterpret_cast not static cast.  Where do you
find otherwise?

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                       ]