Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I assign the wrong enum element, but can compare against the wrong enum element?

With the following C++ definitions:

enum EnumA {
    EA_Element = 1
};

enum EnumB {
    EB_Element = 10
};

the following code won't compile and that only makes sense:

EnumA variable;
variable = EB_Element; // won't compile

but the following code does compile:

EnumA variable = EA_Element;
if( variable == EB_Element ) { //will compile
}

although it can't make any sense - different enums are compared and such code is likely erroneous.

Why are these seemingly identical situations handled differently in C++?

like image 478
sharptooth Avatar asked Jul 06 '11 06:07

sharptooth


4 Answers

It will compile because "By default enums are converted to integers for arithmetical operations." (In: The C++ programming language)

like image 69
imbaer Avatar answered Nov 01 '22 10:11

imbaer


That argument is correct as, I have seen that any enum type can be compared to any enum type. That's because for comparison purpose, enum variables and values should be converted to integral type (such as int). Certain compiler do raise the warning.

Such argument can hold true for comparison between unsigned int, int, size_t etc., but may be they all are limited to a compiler warning for the same reason.

However, this issue is addressed in C++0x with enum class (they haven't changed the existing enum behavior to maintain compatibility).

like image 43
iammilind Avatar answered Nov 01 '22 12:11

iammilind


Its not that its impossible, its just that your compiler considers them to be two different data types when they are both just integers. So a simple typecast would resolve the issue.

EnumA variable;
variable = (EnumA)EB_Element;
like image 2
Drake Avatar answered Nov 01 '22 11:11

Drake


Welcome to C++!

for something even funnier try this:

#include <string>

int main(int argc, const char *argv[])
{
    std::string s;
    s = 3.141592654;
    return 0;
}

why does it compile? The reason is that the language rules say so.

In this funky case the "official" explanation about why this example compiles is that it seemed right to allow std::string::operator+=(char) (IMO ok and logical from a pragmatic point of view) and "therefore" also assignment from char (IMO illogical non-sequitur). But chars are ints (illogical, but C heritage) and doubles can be implicitly converted to ints (illogical, but C heritage). Therefore in C++ it's illogical (but legal) to assign a double to a string.

Don't feel bad if you didn't know, most C++ programmers I shown this were puzzled by why such a nonsense compiles and thought about either other semantic or compiler bugs.

In the case of your question the reason is that enums are like ints in some context (probably because of heritage on use cases) but not like ints in some other context. It's absurd but it's what the standard mandates.

If you feel uncomfortable with this apparently absence of logic please remember that C++ is mostly the result of a long history and even of a committee (!) so logic doesn't really have much to do with it. This also implies that one cannot use logic to avoid studying C++: no matter how intelligent you are there is no way you can guess historic accidents and committee political decisions.

The high C++ complexity, this absence of logic in many places and the presence of undefined behavior daemons instead of runtime error angels is also what IMO basically rules out learning C++ by experimentation.

Pick a good book (or a few) and read it (them) cover to cover... unfortunately there is no other way. My suggestions are: "The C++ Programming Language" (Stroustrup), "Effective C++" & "More effective C++" (Meyers), "C++ FAQs" (Cline/Lomow/Girou).

C++ is a pretty powerful and nice weapon to own, but approach it from the wrong side and it can just become the worst of your nightmares. Assuming that you can understand it just using logic is a wrong approach (and not because your logic is weak, but because C++ is not just logic).

like image 1
6502 Avatar answered Nov 01 '22 10:11

6502