[C++] Proper enum usage

Started by
19 comments, last by Antheus 14 years, 2 months ago
Wow, thank you guys for those very interesting reflections. If I understand things correctly: it should not cause me problems to just pass one enum element as an argument in my custom functions and use for comparison with the same enum elements as long as they are within the same program on the same machine?

So far I have only checked for equivalence as such:

	if( grade == ERRORGRADE::TERMINATE )	{		PostQuitMessage( 0 );	}	else if( grade == ERRORGRADE::TERMINATEANDMSG )	{		std::string message = text1 + text2;		MessageBox( 0, message.c_str(), "Critical Error", MB_OK | MB_ICONSTOP | MB_APPLMODAL );		PostQuitMessage( 0 );	}


I like the idea of using an enum to control a switch, since it seems to accept the enum as an integral variable. Is this a situation where its usage might be considered unsafe?
Advertisement
Quote:Original post by popsoftheyear
These are cases where the actual value of the identifier is really irrelevant, but they just need to be unique. And we don't want to use a CompressionType where we want to know which HlsBand we are using. Are these not good candidates for enums??


If you get a consensus across all developers that enums are not ints, and that there is no relation between those, unless via from_int/to_int, then they are suitable.

In practice and for historical, practical or cultural reasons, enums and ints are used interchangeably, offering no advantage.

As with everything in C++, one needs to settle on a subset of features to be productive. In case of enums, treating them as named ints is not beneficial, despite language not only allows it, but historically design was in favor of it.

Otherwise, code will rot over time, which brings us full circle. At some point, someone will simply need to use an int instead of an enum, and will force one into another.

Hence, strongly typed values are likely better, but they add complexity and verbosity. They can however result in perfectly safe code, which is still convenient to use.

It's just the age-old C++ issue, jack of all trades, master of none. It can be trained, but requires considerable upfront work on boiler-plate functionality.
@Washu
I feel perhaps I should explain this particular implementation a bit better.

The whole application is built upon classes that return either success or failure when they are initiated, so should any call return false it will attempt to close down along the "function call branch" back into the main loop which would end seeing as a quit message was posted.

I'm sure this isn't the most fool-proof implementation, but all I really want to do with the enum is to provide myself with a lazy way of managing what each individual error call will do as I manually write the calls into the rest of the code.

I only really want critical errors at the "end" of a function call branch to display a message box, to let the user know what really caused all the trouble. The rest of the error calls should only log the error in a text file.

This probably washes out the discussion a bit but I really appreciate all of your concern :)
Quote:Original post by swiftcoder
Nope, an enum is just a name. That C/C++ choose to implement them in terms of integers is immaterial.


This is true, but it's also silly. In my mind, the most intuitive use for something like an enum is to simply be a wrapper around such const int functionality. Enums SHOULD be the same as const ints. Conceptually, there's really no reason to ever use enums... in fact, they're kind of a trap. For what you would intuitively think they're useful for, they are actually undefined :(
Quote:Original post by Vanderry

The whole application is built upon classes that return either success or failure when they are initiated, so should any call return false it will attempt to close down along the "function call branch" back into the main loop which would end seeing as a quit message was posted.

This is what exceptions do.

Quote:I only really want critical errors at the "end" of a function call branch to display a message box, to let the user know what really caused all the trouble. The rest of the error calls should only log the error in a text file.


These are two different things, one is logging, the other are fatal errors, so they can't be handled in same way.
try {  while (...) {    // main loop stuff    log(INFO, "Hello world"); // don't quit, just log    try {      load_stuff();    } catch (file_not_found_exception & e) {      log(WARNING, "It's ok, file might not exist");    }  }} catch (std::exception & e) {  // unhandled exception, nobody caught it, we can't handle it, let's quit  PostQuitMessage( 0 );}
Quote:Original post by Washu
Quote:Original post by Normandy
I'm fairly sure this is a problem they are addressing in C++0x. Right now enums aren't even type-safe, so I presume they would add something like scope resolution for enum members.

C++0x doesn't fix the issue, it just sidesteps the issue by introducing a new type of enumeration, the "enum class" type. The enum class type is type safe, although you can use explicit casting to convert to integral type..


I guess it depends what you mean by "C++0x doesn't fix the issue", but it does indeed cause the values to be scoped to the defining enum class, solving the problem the OP asked about.
Doesn't C++0x also allow you to specify the underlying type of the enum, including allowing non-integer types?
Quote:Original post by theOcelot
Doesn't C++0x also allow you to specify the underlying type of the enum, including allowing non-integer types?


I hadn't heard this. So you could define an enum as being a string?
Quote:Original post by jwezorek
Quote:Original post by theOcelot
Doesn't C++0x also allow you to specify the underlying type of the enum, including allowing non-integer types?


I hadn't heard this. So you could define an enum as being a string?


It actually does still require integral types. Any integral type except wchar_t is suitable.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2347.pdf

See section 3.1 specifically.
I must say that I'm a bit surprised so many of you oppose the use of enums when it seems so widely used, not the least in many professional DirectX-applications I have studied. I guess that might be one of those fields where their pros outweigh their cons.

This topic is closed to new replies.

Advertisement