Topic: reinterpret_cast rejected for Int to Enum
Author: "Jim Cobban" <jcobban@nortel.ca>
Date: 1998/03/11 Raw View
In article <3504B0BB.C40C1B42@ix.netcom.com>,
Paul D. DeRocco <pderocco@ix.netcom.com> wrote:
>Personally, for non-platform-dependent casts, i.e. those among basic
>numeric types and enums, I prefer functional notation:
>
> enum my_enumeration { a, b, c };
>
> my_enumeration x = my_enumeration(2);
>
>The angle-bracket casts are nice for constructs that may be
>platform-dependent, and that may need editing during porting, but
>converting numbers to enumerators isn't one of those cases. In fact, such
>casts often occur in situations where you know the number will fit into
>the enumeration, e.g.:
>
> my_enumeration x = my_enumeration(a | b);
>
>The functional notation mimics what it would look like if my_enumeration
>was a class with a constructor taking an int parameter.
You must have missed the beginning of the discussion. The concern is that
C++ is a little too accepting of assignments from integers to enumerations.
They can be performed by a static_cast, a function style cast, or a
traditional C cast (although we aren't supposed to use those any more). The
problem is that none of these warn you that the assignment may be invalid.
For example how do I get the compiler to warn me if I attempt to assign the
value 4 to an instance of my_enumeration? I cannot even get my compiler
(gcc 2.7.1) to object when there are more bits in the integer value I am
trying to assign than there are in the target enumeration value. I am not
permitted to define an operator = or a constructor for an enumeration since
an operator = or a constructor must be a non-static member function. To get
around this I have to define the enumeration as a class, which is clumsy.
I am permitted to explicitly define some operators, for example operator ++
can be defined to only generate valid values for the enumeration.
Using a function style cast for an enum completely hides the fact that there
can be problems with this assignment. It is also misleading because it
suggests that the type has a constructor. Thirdly you cannot grep your code
to identify suspect assignments. Fourthly, contrary to your statement, an
assignment from int to enum is implementation dependent, since there is no
guarantee as to how many bits there are in an enum. The static_cast is a
little more alarming since it does make it clear that the resulting
conversion may not be exactly what you had in mind. But it still does not
warn of invalid assignments.
--
Jim Cobban | jcobban@nortel.ca | Phone: (613) 763-8013
Nortel (MCS) | | FAX: (613) 763-5199
| "I am not a number. I am a human being!"
| P. McGoohan, "The Prisoner"
---
[ 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: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1998/03/10 Raw View
Pablo Halpern wrote:
>
> #define enum_cast static_cast
>
> enum X { a, b, c };
>
> X x = enum_cast<x>(2);
>
> It's not fool-proof. It's not beautiful. It could be used to
> deliberately obfuscate code. But, used as directed, it will work and
> is
> less verbose than the comment. However, I generally consider
> static_cast<> to be almost as much of a red flag as reinterpret_cast<>
> so I just use it to mark dangerous conversions.
Personally, for non-platform-dependent casts, i.e. those among basic
numeric types and enums, I prefer functional notation:
enum my_enumeration { a, b, c };
my_enumeration x = my_enumeration(2);
The angle-bracket casts are nice for constructs that may be
platform-dependent, and that may need editing during porting, but
converting numbers to enumerators isn't one of those cases. In fact, such
casts often occur in situations where you know the number will fit into
the enumeration, e.g.:
my_enumeration x = my_enumeration(a | b);
The functional notation mimics what it would look like if my_enumeration
was a class with a constructor taking an int parameter.
--
Ciao,
Paul
---
[ 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: phalpern@truffle.ma.ultranet.com (Pablo Halpern)
Date: 1998/03/06 Raw View
"Jim Cobban" <jcobban@nortel.ca> wrote:
> // I wanted to use a reinterpret_cast<> to flag the following as
> // dangerous but the f**king language gods won't let me
>
>so it will show up when I grep my source.
#define enum_cast static_cast
enum X { a, b, c };
X x = enum_cast<x>(2);
It's not fool-proof. It's not beautiful. It could be used to
deliberately obfuscate code. But, used as directed, it will work and is
less verbose than the comment. However, I generally consider
static_cast<> to be almost as much of a red flag as reinterpret_cast<>
so I just use it to mark dangerous conversions.
-------------------------------------------------------------
Pablo Halpern phalpern@truffle.ultranet.com
I am self-employed. Therefore, my opinions *do* represent
those of my employer.
---
[ 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: stephen.clamage@sun.com (Steve Clamage)
Date: 1998/03/03 Raw View
In article qau@bcarh8ab.bnr.ca, "Jim Cobban" <jcobban@nortel.ca> writes:
>
>enum TestEnum { A,B,C };
>int main()
>{
> TestEnum x;
> x = reinterpret_cast<TestEnum>(1);
>}
>
>I want to use reinterpret_cast to warn myself that what I am doing is
>dangerous. ... the formal definition of reinterpret_cast which lists
>specifically those conversions which are permitted, which does not include
>enumeration to integer.
Why not use static_cast? Any use of static_cast is potentially
dangerous, so it fits with your stated purpose.
---
Steve Clamage, stephen.clamage@sun.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: phalpern@truffle.ma.ultranet.com (Pablo Halpern)
Date: 1998/02/23 Raw View
"Jim Cobban" <jcobban@nortel.ca> wrote:
> // I wanted to use a reinterpret_cast<> to flag the following as
> // dangerous but the f**king language gods won't let me
>
>so it will show up when I grep my source.
#define enum_cast static_cast
enum X { a, b, c };
X x = enum_cast<x>(2);
It's not fool-proof. It's not beautiful. It could be used to
deliberately obfuscate code. But, used as directed, it will work and is
less verbose than the comment. However, I generally consider
static_cast<> to be a red flag, anyway, so I don't worry too much about
missing an int-to-enum cast.
-------------------------------------------------------------
Pablo Halpern phalpern@truffle.ultranet.com
I am self-employed. Therefore, my opinions *do* represent
those of my employer.
[ 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: "Jim Cobban" <jcobban@nortel.ca>
Date: 1998/02/21 Raw View
In the following program gcc-V2.7-97r1b accepts all of the assignments to
the instance of the enumeration EXCEPT the reinterpret_cast. Considering
that there is no guarantee that a specific int can be assigned as a value to
an enum I would have thought that reinterpret_cast should have been the only
accepted C++ form:
enum TestEnum { A,B,C };
int main()
{
TestEnum x;
x = TestEnum(1);
x = (TestEnum)1;
x = static_cast<TestEnum>(1);
x = reinterpret_cast<TestEnum>(1);
}
I want to use reinterpret_cast to warn myself that what I am doing is
dangerous. The failure of the the compiler to permit me to use
reinterpret_cast means that this dangerous activity goes unflagged. This
behavior is sanctioned by the draft C++ standard in paragraph 7 of section
5.2.9 Static cast:
"A value of integral type can be explicitly converted to an enumeration
type. The value is unchanged if the integral value is within the
range of the enumeration values (_dcl.enum_). Otherwise, the resulting
enumeration value is unspecified."
and also by the formal definition of reinterpret_cast which lists
specifically those conversions which are permitted, which does not include
enumeration to integer. However it disagrees with the spirit of the
distinction between static and reinterpret casts which is expressed by
Stroustrup in "The C++ Programming Language" 3rd edition section 6.2.7.
Presumeably this is an exception which has been made to avoid obsoleting
millions of lines of code which already use constructor style or static
casts, but why outlaw reinterpret_cast for those who want to remind
themselves that this is a dangerous practice?
If the language definition is not prepared to permit me to use a
reinterpret_cast to flag this dangerous practice then I will have to precede
every line of code in which I find myself forced to do a conversion from int
to enum with a comment of the form:
// I wanted to use a reinterpret_cast<> to flag the following as
// dangerous but the f**king language gods won't let me
so it will show up when I grep my source.
--
Jim Cobban | jcobban@nortel.ca | Phone: (613) 763-8013
Nortel (MCS) | | FAX: (613) 763-5199
| "I am not a number. I am a human being!"
| P. McGoohan, "The Prisoner"
---
[ 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 ]