Jump to page: 1 2
Thread overview
Question on @nothrow
May 31, 2017
Mike Parker
May 31, 2017
Ali Çehreli
Jun 01, 2017
Ali Çehreli
Jun 01, 2017
Ali Çehreli
Jul 05, 2017
Ali Çehreli
May 31, 2017
Jonathan M Davis
Jul 05, 2017
Yuxuan Shui
Jul 05, 2017
Yuxuan Shui
May 31, 2017
Hi,

after reading various articles bout the "supposed" drawbacks of checked exceptions I started to have questions on @nothrow. Why there exists and not a @throws annotation enforced by the compiler? I understand that people are divided on checked exceptions and each side has some valid points. But explicitly marking a function as throwing "something" is another subject. Why have the dlang community reached to the decision to use @nothrow and not a @throws?

May 31, 2017
On Wednesday, 31 May 2017 at 08:18:07 UTC, Vasileios Anagnostopoulos wrote:
> Hi,
>
> after reading various articles bout the "supposed" drawbacks of checked exceptions I started to have questions on @nothrow. Why there exists and not a @throws annotation enforced by the compiler? I understand that people are divided on checked exceptions and each side has some valid points. But explicitly marking a function as throwing "something" is another subject. Why have the dlang community reached to the decision to use @nothrow and not a @throws?

This has come up several times over the years. For summary, go to the search bar and type:

 "checked exceptions" Walter

This will lead you to a number of choice quotes from Walter on the topic. Examples:

"C++98 had checked exceptions (exception specifications), too. Another failure of the idea, it failed so badly hardly anyone but language lawyers ever knew it had it."

"Checked exceptions is another feature that looks great on paper; it's only after years of use one discovers what a perniciously bad feature it is."

I didn't go further, but there are probably some with more detail if you dig, and comments from several others on both sides. There's also this article he linked:

http://www.mindview.net/Etc/Discussions/CheckedExceptions
May 31, 2017
On Wednesday, 31 May 2017 at 08:52:51 UTC, Mike Parker wrote:
>
> This has come up several times over the years. For summary, go to the search bar and type:
>
>  "checked exceptions" Walter


Do you realize that I do not talk about checked exceptions, only a compiler enforced @throws and nothing else?
May 31, 2017
On Wednesday, May 31, 2017 08:18:07 Vasileios Anagnostopoulos via Digitalmars-d-learn wrote:
> Hi,
>
> after reading various articles bout the "supposed" drawbacks of checked exceptions I started to have questions on @nothrow. Why there exists and not a @throws annotation enforced by the compiler? I understand that people are divided on checked exceptions and each side has some valid points. But explicitly marking a function as throwing "something" is another subject. Why have the dlang community reached to the decision to use @nothrow and not a @throws?

Well, if you're not doing checked exceptions, the interesting question is really what _doesn't_ throw rather than what throws, because if the compiler knows that a function doesn't throw, it can optimize out the exception handling mechanisms that are normally required. Also, if nothrow wasn't there originally (and it probably wasn't), then adding an attribute to indicate that a function doesn't throw wouldn't have broken any existing code, whereas adding an attribute to indicate that an exception does throw would have broken all existing code that used exceptions. Also, given that exceptions are the normal error-handling mechanism for D, it makes more sense to allow them by default than to disallow them by default.

Ultimately though, since one is a negation of the other, either an attribute indicating that a function does throw or one indicating that a function doesn't throw would work. Logically, they're the same. It's just a question of which makes more sense as a default and what effect adding the attribute would have had when it was originally introduced, both of which imply that nothrow is the better choice, even if it could have gone either way.

Regardless, nothrow is what we have, and there really wouldn't be any benefit to switching it to throw (or throws or whatever) even if breaking code weren't a concern.

- Jonathan M Davis

May 31, 2017
On Wednesday, 31 May 2017 at 09:31:48 UTC, Jonathan M Davis wrote:
> [...]

Thank you for the answers.
May 31, 2017
On 05/31/2017 02:10 AM, Vasileios Anagnostopoulos wrote:

> compiler enforced @throws

For that to be possible, the compiler would have to see all definitions, which is not possible with separate compilation.

Besides, I think the only meaning of @throws would be "may throw". If so, since the implementation of every function can be changed to call any other function, the possibility of throwing would always exist.

Ali

June 01, 2017
On Wednesday, 31 May 2017 at 17:20:08 UTC, Ali Çehreli wrote:
> On 05/31/2017 02:10 AM, Vasileios Anagnostopoulos wrote:
>
> > compiler enforced @throws
>
> For that to be possible, the compiler would have to see all definitions, which is not possible with separate compilation.
>
> Besides, I think the only meaning of @throws would be "may throw". If so, since the implementation of every function can be changed to call any other function, the possibility of throwing would always exist.
>
> Ali


So the biggest question is, how do I know that a function "may throw" an exception in order to use a try/catch/finally block? This is my biggest problem (sorry, coming from a java/C background).
June 01, 2017
On 06/01/2017 06:26 AM, Vasileios Anagnostopoulos wrote:

> how do I know that a function "may throw" an
> exception in order to use a try/catch/finally block? This is my biggest
> problem (sorry, coming from a java/C background).

I come from a C++ background so the advices may be different from Java's.

The liberating thing about exceptions is that you simply do not catch them. In fact, you're adviced against catching them unless you want to or can do something when they are thrown.

If you think that way, you write your code to do its resource management automatically with destructors, scope statements (scope(exit), scope(exception), and scope(success)), etc.

Say, you want to send a letter by performing certain steps: grab a paper, write the letter, grab an envelope, put the letter inside, oops, there is no stamp. Throw an exception... If such low or intermediate level functions have no idea what the higher layer application code wants to do in this case, they simply throw. N layer up, a function would want to catch an Exception, log "failed to send to Ali because no stamp." So, nobody cared in this example who could throw. They simply did their tasks. Of course, it's not always as simple in practice but you almost never need to catch exceptions from individual functions.

To contrast, C's error handling is too cumbersome as every single programming step must at least be two lines: first do it and then check the error code. (Go famously claims that it followed C in this regard for simplicity. Since they made other claims and have shown ignorance especially at the time of Go's introduction, I will never believe Go adopted C's error handling for simplicity.)

Ali

June 01, 2017
On Thursday, 1 June 2017 at 15:17:32 UTC, Ali Çehreli wrote:
> On 06/01/2017 06:26 AM, Vasileios Anagnostopoulos wrote:
>
> > how do I know that a function "may throw" an
> > exception in order to use a try/catch/finally block? This is
> my biggest
> > problem (sorry, coming from a java/C background).
>
> I come from a C++ background so the advices may be different from Java's.
>
> The liberating thing about exceptions is that you simply do not catch them. In fact, you're adviced against catching them unless you want to or can do something when they are thrown.
>
> If you think that way, you write your code to do its resource management automatically with destructors, scope statements (scope(exit), scope(exception), and scope(success)), etc.
>
> Say, you want to send a letter by performing certain steps: grab a paper, write the letter, grab an envelope, put the


Let us emulate this as function calls with void


void sendEmailToAli() {

grabAPaper();
writeALetter();
grabAnEnvelope();
putTimeStamp(); //throws an Exception, function not in my control, residing in a dll
putToMailBox();

}

> letter inside, oops, there is no stamp. Throw an exception... If such low or intermediate level functions have no idea what the higher layer application code wants to do in this case, they simply throw. N layer up, a function would want to catch



//If I knew about the exception
//I could recover, because exceptions
//signal recoverable errors

void haveToCommunicateWithAli() {
try {

sendEmailToAli();

} catch(Exception e) {

goPersonallyToAli();

}
}


//If I do not know

void haveToCommunicateWithAli() {
sendEmailToAli();
}

//can blow-up after code has shipped
//and have no chance to recover


What shall I do in this case? Thank you in advance.

Vasileios
June 01, 2017
On 06/01/2017 08:41 AM, Vasileios Anagnostopoulos wrote:

> //If I do not know
>
> void haveToCommunicateWithAli() {
> sendEmailToAli();
> }
>
> //can blow-up after code has shipped
> //and have no chance to recover
>
>
> What shall I do in this case? Thank you in advance.
>
> Vasileios

(Sorry if I go to too basic levels here.) I used to think that an unhandled exception was a program crash. It's not. It's a good thing that a program aborts due to an uhandled exception. What happened is that it could not achieve it's task. There was nothing else it could do, so it terminated. (For example, it did not continue with unhealthy radiation levels on the patient.)

Although an abort may be the safest thing to do in many cases, it's not user-friendly. So, you catch the exception at the highest level that it matters or that you can do something about it. For example, you can catch the exception in main(), report a friendly error, and return 1.

Or, you may be in a loop, preparing letters, you catch around that code and either report an error or perhaps grab more stamps and repeat the last operation.

So the answer is, don't catch exceptions any lower than it really matters, which could be as high as the main() function.

Ali

« First   ‹ Prev
1 2