From -4897393995227185944
X-Google-Language: ENGLISH,ASCII
X-Google-Thread: f78e5,11af4794c44339e8,start
X-Google-Attributes: gidf78e5,public
From: Ron Burk <ronburk@gte.net>
Subject: Can you static_cast between enums?
Date: 1999/12/07
Message-ID: <ktA14.377$6A5.16841@dfiatx1-snr1.gtei.net>#1/1
X-Deja-AN: 557741632
Content-Transfer-Encoding: QUOTED-PRINTABLE
Approved: Fergus Henderson <fjh@cs.mu.oz.au>
X-Original-Date: Thu, 02 Dec 1999 20:17:20 +0000 (GMT)
Content-Type: TEXT/PLAIN
X-MIMEOLE: Produced By Microsoft MimeOLE V4.72.3110.3
X-Abuse-Info: Otherwise we will be unable to process your complaint properly
X-Complaints-To: news@news.unimelb.edu.au
X-Trace: ariel.ucs.unimelb.edu.au 944581950 21503 128.250.37.153 (7 Dec 1999 15:52:30 GMT)
Organization: -
X-Auth: PGPMoose V1.1 PGP comp.std.c++ iQBFAgUAOE0tQeEDnX0m9pzZAQH4BQGAhcI0RRuq/XkDOGii4xSOTNM1xxZIVjb4 bkXvSP6aveDknK7zfusQSFEBbAEi9aU6 =g+xi
Mime-Version: 1.0
NNTP-Posting-Date: 7 Dec 1999 15:52:30 GMT
Newsgroups: comp.std.c++

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              ]



