//in some class or namespace:
typedef unsigned int error_code;
const error_code out_of_mem = 0x01,
niggers = 0x02,
jews = 0x04;
error_code f()
{
error_code ret = 0;
//do some stuff...
//suddenly niggers
ret |= niggers;
//but it's not a fatal error so we will continue execution
//...
if(some_pointer == nullptr)
{
ret |= out_of_mem;
goto cleanup;
}
//and so on...
cleanup:
delete some_pointer;
//etc...
return ret;
}
void implementation()
{
error_code f = f();
if( f & out_of_mem )
//handle error
printf("%s\n", "allocation failure");
if( f & niggers )
pool.close();
}
The main point of exceptions is to separate error detection from error handling. This accomplishes that. If you need the advanced features of exceptions, take a good look at your design and, more importantly, your life.
Name:
Anonymous2012-07-04 20:58
goto cleanup;
WHAT ARE YOU DOING!?
Name:
Anonymous2012-07-04 21:11
wow dude you have made a hatchet job of this. learn to write proper code. no goto's, no custom error codes unless your codebase is the size of my dick (which is huge)
Name:
Anonymous2012-07-04 21:20
NO EXCEPTIONS
Name:
Anonymous2012-07-04 21:20
>>3
The goto is necessary to avoid resource/file leaks. Note that you don't get this with exceptions unless you use smart pointers. And smart pointers consume a massive class for a fucking pointer of all things, where a couple simple jump instructions would have sufficed.
Name:
Anonymous2012-07-04 21:34
>>3
Yeah, but your program now has run into a serious problem: it's run out of available memory, but it may not stop trying to do things that it would normally do. Continuing as things are could create problematic states elsewhere, jeopardizing stability or configuration, and you wouldn't notice until the damage became significant or unless you checked an error log.
Sure, you can just quit the program here if the problem detected is that serious; I'm not saying that. But that still means having to put redundant code that handles the affairs of reporting back to the user/developer what went wrong and where.
>>6
Exceptions don't deal with (no available memory) any better than this does.
And I don't see how comparing integers is redundant code. It's something so quick and trivial that it doesn't take a second's more thought than throw some ugly exception. And it's more efficient. Prove me wrong.
Name:
Anonymous2012-07-04 23:32
>>8
I said error logging/reporting, not the conditional. If the same error is encountered in multiple places, everywhere that can be a problem has to have a copy of that code. It's likely that the same kind of error isn't handled radically different in different parts of the code and anything that's recoverable shouldn't need to be an exception-worthy issue anyway. Showstoppers, but not general cleanup, like what the OP could do by just failing early and gracefully. The goto is superfluous.
If we're ruling out exceptions because they do not deal with out of memory conditions any better than goto'ing somewhere else, then the OP example can not be considered a valid example of an argument for branching instead of exceptions and I request a more suitable one. In this state, the program is still doing things and can potentially enter half-states where one part begins misbehaving while the other part gives the impression that it's working correctly. That does depend on how you what the problem is and how you can handle it, admittedly, but it's not usually good.
Name:
Anonymous2012-07-05 0:37
I need exceptions because I HATE GLOBAL VARIABLES THEY ARE THE DEVIL.
Name:
Anonymous2012-07-05 1:13
implying C++'s runtime isn't already using exceptions en mas
Who needs exceptions?
I know it's not really /prog/'s style, but I will take a shot at actually answering the question asked by >>1, since it's a programming question.
No one "needs" exceptions, but they are very convenient and efficient in certain situations. A common example is when you write deeply recursive code, as in any type of parser. When you encounter a parse error, your options are to either return some failure code up through dozens of levels of call stack -- meaning that you'll have to check the return value at every level, as well (inefficient) -- or to just throw an exception immediately when the error is encountered and catch at the top level.
Another reason to use them is that they make code more readable. They separate the actual "functional" code from the error handling code.
Without exceptions:
error_code e = init_driver();
if (e == error_device_not_ready)
...
else if (e == error_device_already_initialized)
...
else if (e == ...)
...
e = get_device_status(status);
if (e == error_device_not_ready)
...
else if (e == error_unsupported)
...
else if (e == ...)
...
e = write_data_to_device(data);
if (e == error_device_not_ready)
...
else if (e == error_wrong_data_format)
...
else if (e == ...)
...
They can be useful for things like event handlers, where you don't want an event handler to take your program down, so you can wrap the whole notification in a try/catch.
But I don't agree with functions from a language's standard library throwing stuff from simple functions.
HURR DURR OPEN throws FILENOTFOUNDEXCEPTION. That shit can fuck off.
>>22
Wut. How, in any implementation, can returning an integer be less efficient than exceptions? Have you seen all the instructions a single throw and catch pair introduce?
Exceptions are fucking unnecessary, harmful shit.
Name:
Anonymous2012-07-09 0:46
>Who needs exceptions?
Java programmers
Name:
Anonymous2012-07-09 1:09
>>26
Java programmers are the exceptions that I wish to throw.
Using the CPU's carry flag for returning boolean values and signaling errors: It's been over 30 years since the 8086 was released, and we are finally seeing some of these established efficient customs of asm propagating to the first level of high-level languages. Nothing can beat the 1 + 2n bytes needed to return a boolean like this (1 byte to set, 2 bytes to test+jump per callsite); the best C compilers will generate a 2 + 4n (2 bytes to set, 2 bytes to test + 2 bytes to jump per callsite).
See also: custom calling conventions, return address retargeting, cross-function register allocation, etc.