Topic: Can you static_cast between enums?
Author: David R Tribble <david@tribble.com>
Date: 1999/12/17 Raw View
"J.Barfurth" wrote:
[...]
> After that paragraph follow the interesting rules, which tell you what
> static_cast can do, but can't be done without a cast.
> The relevant one states that static_cast can convert from any integral
> type to an enumeration type. As others have stated that does not allow
> the cast from one enumeration type to another.
So what does the following expression do, in terms of the xxx_cast
operators?
enum Color { RED, WHITE, BLUE };
enum Hue { R, W, B };
Hue h = (Hue)RED; // not static_cast<Hue>(RED)?
-- David R. Tribble, david@tribble.com, http://david.tribble.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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: wmm@fastdial.net
Date: 1999/12/18 Raw View
In article <385AA7AA.8D983B3@tribble.com>,
David R Tribble <david@tribble.com> wrote:
>
> "J.Barfurth" wrote:
> [...]
> > After that paragraph follow the interesting rules, which tell you
what
> > static_cast can do, but can't be done without a cast.
> > The relevant one states that static_cast can convert from any
integral
> > type to an enumeration type. As others have stated that does not
allow
> > the cast from one enumeration type to another.
>
> So what does the following expression do, in terms of the xxx_cast
> operators?
>
> enum Color { RED, WHITE, BLUE };
> enum Hue { R, W, B };
>
> Hue h = (Hue)RED; // not static_cast<Hue>(RED)?
None of the casting mechanisms -- "(Hue)RED", "Hue(RED)", and
"static_cast<Hue>(RED)" -- allows this conversion, according to
the current wording of the standard. As I said earlier in this
thread, this is an oversight and is expected to be corrected in
the first Technical Corrigendum.
--
William M. Miller, wmm@fastdial.net
OnDisplay, Inc. (www.ondisplay.com)
Sent via Deja.com http://www.deja.com/
Before you buy.
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jpotter@falcon.lhup.edu (John Potter)
Date: 1999/12/20 Raw View
On 18 Dec 1999 23:24:34 GMT, wmm@fastdial.net wrote:
:
: In article <385AA7AA.8D983B3@tribble.com>,
: David R Tribble <david@tribble.com> wrote:
: > So what does the following expression do, in terms of the xxx_cast
: > operators?
: >
: > enum Color { RED, WHITE, BLUE };
: > enum Hue { R, W, B };
: >
: > Hue h = (Hue)RED; // not static_cast<Hue>(RED)?
:
: None of the casting mechanisms -- "(Hue)RED", "Hue(RED)", and
: "static_cast<Hue>(RED)" -- allows this conversion, according to
: the current wording of the standard. As I said earlier in this
: thread, this is an oversight and is expected to be corrected in
: the first Technical Corrigendum.
Hue h(static_cast<Hue>(static_cast<int>(RED)));
is a bit messy. Is the following also an oversight?
struct S { int x, y };
S s;
int* p(static_cast<int*>(static_cast<void*>(&S)));
We are assured that the address of the struct may be cast to the
address of the first element; however, it must either be an
implementation defined reinterpret_cast or a double cast with no
assurances that it will work. 5.2.9/10 does not say "except that"
like 5.2.10/*, but seems to make it questionable.
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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "J.Barfurth" <techview@bfk-net.de>
Date: 1999/12/14 Raw View
Ron Burk <ronburk@gte.net> schrieb in im Newsbeitrag:
ktA14.377$6A5.16841@dfiatx1-snr1.gtei.net...
> Mark Wilson submitted this to our Bug++ column, and I'm
> having trouble proving what's right from the standard. In
> a nutshell, the question is: can static_cast cast between
> different enums?
> Finally, section 7.2.9 says "An expression of arithmetic or
enumeration
> type can be converted to an enumeration type explicitly."
> I next turned to the text on static_cast, of which there is quite a
bit.
> However, the key point for this problem seemed to be in the second
> paragraph of section 5.2.9, which says in part: "An expression e can
> be explicitly converted to a type T using a static cast of the form
> static_cast<T>(e) if "T t(e);" is well-formed, for some invented
> temporary variable t."
I don't think this part is relevant here. It does not even apply to
static_cast from integral type to enum.
This paragraph only allows static_cast (a) to do any implicit conversion
explicitly as well and (b) to use constructors for class types (even
explicit ones) - possibly after an implicit conversion sequence.
After that paragraph follow the interesting rules, which tell you what
static_cast can do, but can't be done without a cast.
The relevant one states that static_cast can convert from any integral
type to an enumeration type. As others have stated that does not allow
the cast from one enumeration type to another.
> In any case, more than one compiler author apparently disagrees
> about what the rules are here. Can someone give me better reasoning
> from the standard to say:
>
> a) is the static_cast legal?
It isn't, but that seems a defect. The reference from 7.2.9 shows
that this is intended to be legal.
The paragraph in 5.2.9 which I mentioned should read "... from an
integral or enumeration type ..." as is done in many other places.
In the paragraph you quoted, implicit conversions (e.g. integral
promotions) can be done before using a constructor. In the other
paragraphs that is not possible any more.
> b) should Type2 t(value1); be legal?
It isn't legal and IMHO shouldn't be legal either
-- J=F6rg Barfurth
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Valentin Bonnard <Bonnard.V@wanadoo.fr>
Date: 1999/12/10 Raw View
Bill Wade wrote:
> Ron Burk wrote in message ...
> >enum Type1 {value1, value2};
> >enum Type2 {value3, value4};
>
> > [ are the following legal? ]
> > static_cast<Type2>(value1);
>
> I'm pretty sure the static_cast is legal.
By the letter of the standard, it isn't.
> 7.2/9 must refer to some kind of cast.
Maybe. This kind of arguments don't prove anything
about what the standard says.
> Another argument in favor of static_cast is that standard conversions can be
> applied to arguments of operators where necessary.
No they can't. Things aren't done ``where necessary''.
Things are done as required.
--
Valentin Bonnard
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jpotter@falcon.lhup.edu (John Potter)
Date: 1999/12/08 Raw View
On 07 Dec 99 15:51:47 GMT, Ron Burk <ronburk@gte.net> wrote:
: Mark Wilson submitted this to our Bug++ column, and I'm
: having trouble proving what's right from the standard. In
: a nutshell, the question is: can static_cast cast between
: different enums? The sample code is:
The answer is no. Maybe someone will walk you through it, but
here is an analogy of your logic.
float f;
int* pi = static_cast<int*>(&f);
You know that this is a reinterpret_cast. But, there is a standard
conversion from float* to void* and static_cast of void* to int* is
valid.
There are places where standard conversions are not applied. The
expression to a cast is one of them. I think that this is one of
those things which is said by not saying it. Because the statement
about initialization says 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: zivca@netvision.net.il (Ziv Caspi)
Date: 1999/12/08 Raw View
On 07 Dec 99 15:51:47 GMT, Ron Burk <ronburk@gte.net> wrote:
[...]
>I next turned to the text on static_cast, of which there is quite a b=
>it.
>However, the key point for this problem seemed to be in the second
>paragraph of section 5.2.9, which says in part: "An expression e can
>be explicitly converted to a type T using a static cast of the form
>static_cast<T>(e) if "T t(e);" is well-formed, for some invented
>temporary variable t." Going back to Mark's example, would it be
>legal to declare:
>
> Type2 t(value1);
>
>I don't think so.
[...]
> Ironically, however, Visual C++
>flags this construct as an error, while GCC lets it slide with a warn=
>ing.
[...]
>My second opinion is that VC++ is also wrong. It's clear that the
>standard says you can use static_cast to get from an integer
>to an enumeration, or from an enumeration to an integer
>(which can also be done implicitly), but the test for when
>static_cast works does not seem to pass here. Or I could use the
>same reasoning as with GCC -- you can't both treat Type2 t(value1)
>as an error and then let the static_cast slide without comment.
[...]
I don't follow your reasoning here. The statement you quoted
does not imply that if Type2 t(value1) is ill-formed,
static_cast<Type2>(value1) is also ill-formed.
---------------------------------------------
Ziv Caspi
zivca@netvision.net.il
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Bill Wade" <bill.wade@stoner.com>
Date: 1999/12/08 Raw View
Ron Burk wrote in message ...
>enum Type1 {value1, value2};
>enum Type2 {value3, value4};
> [ are the following legal? ]
> static_cast<Type2>(value1);
> Type2 t(value1);
I'm pretty sure the static_cast is legal. 7.2/9 must refer to some kind of
cast. It seems clear that const,dynamic, and reinterpret casts don't work.
Old-style (and function syntax) casts are mostly defined in terms of the new
casts (and the exceptions clearly don't apply).
Another argument in favor of static_cast is that standard conversions can be
applied to arguments of operators where necessary. enum to integer type is
a standard conversion (integral promotion). 5.4/2 says that static_cast is
a conversion operator.
I believe the second is illegal. The applicable part of the standard is the
last "Otherwise" of 8.5/14, at the bottom of page 143:
"... standard conversions will be used to convert [value1 to Type2]. If the
conversion cannot be done, the initialization is ill-formed."
HTH
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Bill Wade" <bill.wade@stoner.com>
Date: 1999/12/08 Raw View
John Potter wrote in message <384dc30d.21459442@news.csrlink.net>...
>On 07 Dec 99 15:51:47 GMT, Ron Burk <ronburk@gte.net> wrote:
>
>: Mark Wilson submitted this to our Bug++ column, and I'm
>: having trouble proving what's right from the standard. In
>: a nutshell, the question is: can static_cast cast between
>: different enums? The sample code is:
>
>The answer is no. Maybe someone will walk you through it, but
>here is an analogy of your logic.
>
>float f;
>int* pi = static_cast<int*>(&f);
A good point. However 7.2/9 effectively says that there is some cast that
will do the conversion of one enum type to another. Which cast works? It
turns out that this is an open issue (#128) on the core language list. So
the real answer is "maybe some day the committee will tell us."
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: wmm@fastdial.net
Date: 1999/12/09 Raw View
In article <82joi7$o4k@library2.airnews.net>,
"Bill Wade" <bill.wade@stoner.com> wrote:
>
>
> Ron Burk wrote in message ...
> >enum Type1 {value1, value2};
> >enum Type2 {value3, value4};
>
> > [ are the following legal? ]
> > static_cast<Type2>(value1);
> > Type2 t(value1);
>
> I'm pretty sure the static_cast is legal. There is an implicit
promotion
> from value1 to some integral type (4.5/2) and static_cast converts
any
> integral type to any enum type (5.2.9/7).
This is the subject of an issue in the core language issues list.
The standard currently says that it is possible to convert from one
enumeration to another (7.2p9). However, the descriptions of
static_cast (5.2.9) and old-style casts (5.4) do not mention this
conversion, and both prohibit conversions that are not explicitly
described. (There's nothing to indicate that the operand of a
static_cast is subject to the integral promotions, so that doesn't
help.)
The intent of the committee, obviously, is that the conversion be
permitted for both static_cast and old-style casts. This is scheduled
to be fixed in the first Technical Corrigendum.
--
William M. Miller, wmm@fastdial.net
OnDisplay, Inc. (www.ondisplay.com)
Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Ron Burk <ronburk@gte.net>
Date: 1999/12/07 Raw View
Mark Wilson submitted this to our Bug++ column, and I'm
having trouble proving what's right from the standard. In
a nutshell, the question is: can static_cast cast between
different enums? The sample code is:
#include <iostream.h>
enum Type1 {value1, value2};
enum Type2 {value3, value4};
int main()
{
Type1 type1 =3D value1;
cout << static_cast<Type2>(type1) << endl;
return 0;
}
Wherein GCC (some version) complained about the static cast,
but Visual C++ 6.0 did not. I began my search through the C++
standard with the definition of enumerations. In section 7.2,
the standard explicitly notes that the following code is illegal:
enum color { red, yellow, green=3D20, blue };
color c =3D 1;
In other words, there's no implicit conversion from integer to
enumeration. However, the following code is legal:
int i =3D yellow;
meaning that an enumeration can be implicitly converted to an integer=
.
Finally, section 7.2.9 says "An expression of arithmetic or enumerati=
on
type can be converted to an enumeration type explicitly." That alone
would imply that VC++ is right and GCC is wrong =96 except that the
statement does not necessarily imply that all means of conversion are
equivalent (though if you're not allowed to convert between enums
with static_cast, a footnote in 7.2.9 might be a handy thing), so
my reading continued.
I next turned to the text on static_cast, of which there is quite a b=
it.
However, the key point for this problem seemed to be in the second
paragraph of section 5.2.9, which says in part: "An expression e can
be explicitly converted to a type T using a static cast of the form
static_cast<T>(e) if "T t(e);" is well-formed, for some invented
temporary variable t." Going back to Mark's example, would it be
legal to declare:
Type2 t(value1);
I don't think so. There's an implicit conversion available to convert
value1 into an integer, but not from an integer to an enumeration
(and besides, I think you don't get to use two implicit conversions t=
o get
where you want to go anyway). Ironically, however, Visual C++
flags this construct as an error, while GCC lets it slide with a warn=
ing.
Well, clearly the standard isn't going to leap up and say explicitly
that you can't static_cast from one enumeration type to another,
so I'm in the area of opinion here. My first opinion is that GCC is
wrong, no matter what. My reasoning is this: you can't treat an
initialization between types as a warning and then treat a static_cas=
t
between those same two types as an error =96 one or the other of
those behaviors should be wrong.
My second opinion is that VC++ is also wrong. It's clear that the
standard says you can use static_cast to get from an integer
to an enumeration, or from an enumeration to an integer
(which can also be done implicitly), but the test for when
static_cast works does not seem to pass here. Or I could use the
same reasoning as with GCC -- you can't both treat Type2 t(value1)
as an error and then let the static_cast slide without comment.
In any case, more than one compiler author apparently disagrees
about what the rules are here. Can someone give me better reasoning
=66rom the standard to say:
a) is the static_cast legal?
b) should Type2 t(value1); be legal?
As another data point, Borland C++ Builder 4.0 believes the
static_cast is legal, and flags the Type2 t(value1) with a warning,
which is almost the same behavior as VC++.
Thanks,
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Bill Wade" <bill.wade@stoner.com>
Date: 1999/12/07 Raw View
Ron Burk wrote in message ...
>enum Type1 {value1, value2};
>enum Type2 {value3, value4};
> [ are the following legal? ]
> static_cast<Type2>(value1);
> Type2 t(value1);
I'm pretty sure the static_cast is legal. There is an implicit promotion
from value1 to some integral type (4.5/2) and static_cast converts any
integral type to any enum type (5.2.9/7).
I believe the second is illegal. The applicable part of the standard is the
last "Otherwise" of 8.5/14, at the bottom of page 143:
"... standard conversions will be used to convert [value1 to Type2]. If the
conversion cannot be done, the initialization is ill-formed."
HTH
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]