Topic: reinterpret_cast from long to long
Author: kanze.james@neuf.fr (James Kanze)
Date: Fri, 2 Jun 2006 20:41:37 GMT Raw View
Greg Herlihy wrote:
> Jens M=FCller wrote:
>> As kanze pointed out in de.comp.lang.c++,
>> long l =3D 42;
>> long& r2 =3D reinterpret_cast<long>(l);
>> is not a valid reinterpret_cast, since a reinterpret_cast from an
>> integral type to an integral type (including the same one) is not=20
defined.
> No, the reason the cast is invalid is due to the mismatched
> types (long vs. long&).
No, the reason the cast is invalid is because the standard
doesn't authorize. A reinterpret_cast cannot be used to convert
an integral type to an integral type (even if both integral
types are the same).
> Correcting the discrepancy fixes the problem:
> long l =3D 42;
> long& r2 =3D reinterpret_cast<long&>(l);
That works, but it has nothing to do with the case we are
discussing.
--=20
James Kanze kanze.james@neuf.fr
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France +33 (0)1 30 23 00 34
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Greg Herlihy" <greghe@pacbell.net>
Date: Sat, 3 Jun 2006 11:08:32 CST Raw View
James Kanze wrote:
> Greg Herlihy wrote:
> > Jens M ller wrote:
> >> As kanze pointed out in de.comp.lang.c++,
>
> >> long l = 42;
> >> long& r2 = reinterpret_cast<long>(l);
>
> >> is not a valid reinterpret_cast, since a reinterpret_cast from an
> >> integral type to an integral type (including the same one) is not
> defined.
>
> > No, the reason the cast is invalid is due to the mismatched
> > types (long vs. long&).
>
> No, the reason the cast is invalid is because the standard
> doesn't authorize. A reinterpret_cast cannot be used to convert
> an integral type to an integral type (even if both integral
> types are the same).
5.2.10/2 states that reinterpret_cast can convert an expression to
its own type:
"Subject to the restrictions in this section, an expression may be cast
to its own type using a reinterpret_cast operator."
Moreover, there is no mention of undefined behavior anywhere in the
description of reinterpret_cast. Instead the entire section enumerates
only those (explicit) conversions that a reinterpret_cast can perform.
There is no language that prohibits reinterpret_cast from performing
non-explicit (or standard) conversions - such as from an int to a long.
So there are two possible ways to interpret the omission: either
reinterpret_cast is able to perform standard conversions or it is not.
And if it is not able to perform a standard conversion, then attempting
to convert an int to a long with a reinterpret_cast would not lead to
undefined behavior - rather the attempted conversion would simply fail
to compile (just as explicit conversions not on the approved list fail
to compile).
But by far the more reasonable position (and the one adopted by C++
compilers) is that reinterpret_cast is not prohibited from performing
standard conversions. And given that a reinterpret_cast compiles away
to nothing (it exists solely to placate the compiler), it is hard to
see how a reinterpret_cast could ever interfere with a standard
conversion - or how its presence would be in that case anything other
than entirely superfluous.
Greg
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: kanze.james@neuf.fr (James Kanze)
Date: Sun, 4 Jun 2006 02:23:16 GMT Raw View
Greg Herlihy wrote:
> James Kanze wrote:
>> Greg Herlihy wrote:
>> > Jens M=FCller wrote:
>> >> As kanze pointed out in de.comp.lang.c++,
>> >> long l =3D 42;
>> >> long& r2 =3D reinterpret_cast<long>(l);
>> >> is not a valid reinterpret_cast, since a reinterpret_cast
>> >> from an integral type to an integral type (including the
>> >> same one) is not defined.
>> > No, the reason the cast is invalid is due to the mismatched
>> > types (long vs. long&).
>> No, the reason the cast is invalid is because the standard
>> doesn't authorize. A reinterpret_cast cannot be used to convert
>> an integral type to an integral type (even if both integral
>> types are the same).
> =A75.2.10/2 states that reinterpret_cast can convert an expression to
> its own type:
> "Subject to the restrictions in this section, an expression
> may be cast to its own type using a reinterpret_cast
> operator."
Yes, *subject to the restirctions in this section*. The
restrictions say that converting an integral type to another
integral type isn't allowed. (Also, of course, the text you
quote is a note, and is not normative.)
> Moreover, there is no mention of undefined behavior anywhere
> in the description of reinterpret_cast.
Who said anything about undefined behavior. The code is
illegal; it requires a compiler diagnostic.
> Instead the entire section enumerates only those (explicit)
> conversions that a reinterpret_cast can perform. There is no
> language that prohibits reinterpret_cast from performing
> non-explicit (or standard) conversions - such as from an int
> to a long.
=A75.2.10/1: "Conversions that can be performed explicitly using
reinterpret_cast are listed below. No other conversion can be
performed explicitly using reinterpret_cast."
> So there are two possible ways to interpret the omission:
> either reinterpret_cast is able to perform standard
> conversions or it is not.
The standard says that if it is not listed, reinterpret_cast
cannot do it.
> And if it is not able to perform a standard conversion, then
> attempting to convert an int to a long with a reinterpret_cast
> would not lead to undefined behavior - rather the attempted
> conversion would simply fail to compile (just as explicit
> conversions not on the approved list fail to compile).
That's exactly what should happen. It is the only alternative;
an attempt to convert a long to a long using reinterpret_cast
requires a diagnostic.
> But by far the more reasonable position (and the one adopted
> by C++ compilers) is that reinterpret_cast is not prohibited
> from performing standard conversions.
The standard explicitly says it is. And at least one compiler
(g++) enforces this.
> And given that a reinterpret_cast compiles away to nothing (it
> exists solely to placate the compiler), it is hard to see how
> a reinterpret_cast could ever interfere with a standard
> conversion - or how its presence would be in that case
> anything other than entirely superfluous.
It's only hard to see if you ignore the standard.
--=20
James Kanze kanze.james@neuf.fr
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France +33 (0)1 30 23 00 34
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: usenet-01-2006@tessarakt.de (=?ISO-8859-15?Q?Jens_M=FCller?=)
Date: Thu, 1 Jun 2006 14:33:55 GMT Raw View
As kanze pointed out in de.comp.lang.c++,
long l =3D 42;
long& r2 =3D reinterpret_cast<long>(l);
is not a valid reinterpret_cast, since a reinterpret_cast from an
integral type to an integral type (including the same one) is not defined.
This is my understanding of [expr.reinterpret.cast] (=A7 5.2.10 in the
C++0x draft, still gotta get the book ...).
Are we correct here?
If so, the newest gcc version is defect here ...
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Tom s" <No.Email@Address.ucar.edu>
Date: Thu, 1 Jun 2006 11:06:15 CST Raw View
> long l = 42;
> long& r2 = reinterpret_cast<long>(l);
That line intends to initialise a non-const reference with an R-value.
If you want any of the C++ casts to result in an L-value, the "cast to"
type must be a reference type.
-Tom s
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: =?UTF-8?B?SmVucyBNw7xsbGVy?= <usenet-01-2006@tessarakt.de>
Date: Thu, 1 Jun 2006 13:26:35 CST Raw View
Jens M ller schrieb:
> As kanze pointed out in de.comp.lang.c++,
>
> long l = 42;
> long& r2 = reinterpret_cast<long>(l);
(About this one, gcc complains)
Hmpf, what I really meant is:
long& r3 = reinterpret_cast<long&>(l);
>
> is not a valid reinterpret_cast, since a reinterpret_cast from an
> integral type to an integral type (including the same one) is not defined.
>
> This is my understanding of [expr.reinterpret.cast] ( 5.2.10 in the
> C++0x draft, still gotta get the book ...).
>
> Are we correct here?
>
> If so, the newest gcc version is defect here ...
And in that case, it seems to depend on how strict you read "different
type":
(Quotes from C++0x draft again, sorry ...)
[expr.reinterpret.cast] #11
| An lvalue expression of type T1 can be cast to the type reference to
| T2 if an expression of type pointer to T1 can be
| explicitly converted to the type pointer to T2 using a
| reinterpret_cast. That is, a reference cast reinterpret_-
| cast<T&>(x) has the same effect as the conversion
| *reinterpret_cast<T*>(&x) with the built-in & and * operators.
| The result is an lvalue that refers to the same object as the source
| lvalue, but with a different type. No temporary is
| created, no copy is made, and constructors (12.1) or conversion
| functions (12.3) are not called.71)
Can "pointer to long" be explicitly converted to "pointer to long" by
reinterpret_cast?
[expr.reinterpret.cast] #11
| A pointer to an object can be explicitly converted to a pointer to an
| object of different type.69) Except that converting
| an rvalue of type pointer to T1 to the type pointer to T2 (where
| T1 and T2 are object types and where the alignment
| requirements of T2 are no stricter than those of T1) and back to its
| original type yields the original pointer value, the
| result of such a pointer conversion is unspecified.
So, as "long" is not a different type than "long", this is forbidden?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Greg Herlihy" <greghe@pacbell.net>
Date: Fri, 2 Jun 2006 00:55:44 CST Raw View
Jens M ller wrote:
> As kanze pointed out in de.comp.lang.c++,
>
> long l = 42;
> long& r2 = reinterpret_cast<long>(l);
>
> is not a valid reinterpret_cast, since a reinterpret_cast from an
> integral type to an integral type (including the same one) is not defined.
No, the reason the cast is invalid is due to the mismatched types (long
vs. long&). Correcting the discrepancy fixes the problem:
long l = 42;
long& r2 = reinterpret_cast<long&>(l);
Of course, now that the types match - it becomes clear that the
reinterpret_cast is not needed. But its presence does no harm either
because a long-to-long type conversion is (at most) an implicit
conversion. And because the conversion is not explicit, it does not
have to appear on the list of explicit conversions defined for the
reinterpret_cast operator.
So the expression (even with the unnecessary reinterpret_cast) has
defined behavior.
Greg
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "kanze" <kanze@gabi-soft.fr>
Date: Fri, 2 Jun 2006 09:56:48 CST Raw View
Tom s wrote:
> > long l = 42;
> > long& r2 = reinterpret_cast<long>(l);
> That line intends to initialise a non-const reference with an
> R-value.
Yes. In the discussions in the German speaking group, the issue
originally raised concerned the error message: some compilers
complained about initializing a non-const reference with an
rvalue, and others about an illegal conversion of long to long.
It turns out that the cast itself is illegal, which should
usually result in the rest of the statement not being
semantically analysed (and thus, no error concerning the binding
of rvalue to a non-const reference).
Jen's point would probably be best addressed if the example
were:
long l2 = reinterpret_cast< long >( l ) ;
> If you want any of the C++ casts to result in an L-value, the
> "cast to" type must be a reference type.
Which is of course true -- changing the reinterpret_cast to
static_cast here would result in a legal cast, but the statement
itself would be illegal.
Another interesting point which was brought up:
long l = 42 ;
long const& r = static_cast< long >( l ) ;
++ l ;
std::cout << l << ", " << r << std::endl ;
According to the standard, this should output "43, 42". G++
4.1.0 gets it right, but a lot of other compilers don't.
--
James Kanze GABI Software
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S mard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Tom s" <No.Email@Address.ucar.edu>
Date: Fri, 2 Jun 2006 12:08:02 CST Raw View
kanze posted:
> Another interesting point which was brought up:
>
> long l = 42 ;
> long const& r = static_cast< long >( l ) ;
> ++ l ;
> std::cout << l << ", " << r << std::endl ;
>
> According to the standard, this should output "43, 42". G++
> 4.1.0 gets it right, but a lot of other compilers don't.
If you think of things along the lines of:
When passing by value, a copy is made.
When returing by value, a copy is made.
Then consider that using static_cast to cast to a non-reference type is
sort of like returning by value -- therefore you'll be working with a copy,
and not the original object.
-Tom s
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: kanze.james@neuf.fr (James Kanze)
Date: Fri, 2 Jun 2006 20:41:08 GMT Raw View
Jens M=C3=BCller wrote:
> Jens M=C3=BCller schrieb:
>> As kanze pointed out in de.comp.lang.c++,
>> long l =3D 42;
>> long& r2 =3D reinterpret_cast<long>(l);
> (About this one, gcc complains)
> Hmpf, what I really meant is:
> long& r3 =3D reinterpret_cast<long&>(l);
I don't think so:-). That one is legal, and works. What you
really meant was either:
long l2 =3D reinterpret_cast< long >( l ) ;
or
long const& r2 =3D reinterpret_cast< long >( l ) ;
In both cases, the only possible error is using a
reinterpret_cast to convert a long to a long.
>> is not a valid reinterpret_cast, since a reinterpret_cast
>> from an integral type to an integral type (including the same
>> one) is not defined.
>> This is my understanding of [expr.reinterpret.cast] (=C2=A7 5.2.10 in=
the
>> C++0x draft, still gotta get the book ...).
>> Are we correct here?
>> If so, the newest gcc version is defect here ...
> And in that case, it seems to depend on how strict you read
> "different type":
> (Quotes from C++0x draft again, sorry ...)
> [expr.reinterpret.cast] #11
> | An lvalue expression of type T1 can be cast to the type=20
\u201creference to
> | T2\u201d if an expression of type \u201cpointer to T1\u201d can be
> | explicitly converted to the type \u201cpointer to T2\u201d using a
> | reinterpret_cast. That is, a reference cast reinterpret_-
> | cast<T&>(x) has the same effect as the conversion
> | *reinterpret_cast<T*>(&x) with the built-in & and * operators.
> | The result is an lvalue that refers to the same object as the source
> | lvalue, but with a different type. No temporary is
> | created, no copy is made, and constructors (12.1) or conversion
> | functions (12.3) are not called.71)
> Can "pointer to long" be explicitly converted to "pointer to
> long" by reinterpret_cast?
Certainly. But the issue in de.comp.lang.c++ was to convert a
long to a long -- no references involved. That was also the
case in your original cast. People just got mislead by the
second error -- trying to bind the results to a non const
reference.
> [expr.reinterpret.cast] #11
> | A pointer to an object can be explicitly converted to a pointer to a=
n
> | object of different type.69) Except that converting
> | an rvalue of type \u201cpointer to T1\u201d to the type=20
\u201cpointer to T2\u201d (where
> | T1 and T2 are object types and where the alignment
> | requirements of T2 are no stricter than those of T1) and back to its
> | original type yields the original pointer value, the
> | result of such a pointer conversion is unspecified.
> So, as "long" is not a different type than "long", this is forbidden?
There's no problem converting any pointer to another pointer
type, nor in converting any lvalue to a reference type. The
problem is when the target is an integral type -- then only
pointers can be converted.
--=20
James Kanze kanze.james@neuf.fr
Conseils en informatique orient=C3=A9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=C3=A9mard, 78210 St.-Cyr-l'=C3=89cole, France +33 (0)1 30 23 00=
34
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]