www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Question on nothrow

reply Vasileios Anagnostopoulos <fithis2001 gmail.com> writes:
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
next sibling parent reply Mike Parker <aldacron gmail.com> writes:
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
parent reply Vasileios Anagnostopoulos <fithis2001 gmail.com> writes:
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
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
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
May 31
parent reply Vasileios Anagnostopoulos <fithis2001 gmail.com> writes:
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).
Jun 01
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
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
Jun 01
parent reply Vasileios Anagnostopoulos <fithis2001 gmail.com> writes:
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
Jun 01
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
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
Jun 01
parent reply Vasileios Anagnostopoulos <fithis2001 gmail.com> writes:
On Thursday, 1 June 2017 at 17:03:52 UTC, Ali Çehreli wrote:
 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
But still I believe that nothrow should be mandatory if there is no possibility for a function to throw something. I understand that in the DLL/LIB level this is not possible. However, at least in the .di level it should be there. And if you want my two cents, after reading a lot I came to the "personal" conclusion that Exception objects are wrong. For me it is enough to have something like void A() { raise; } void B() { raise; } void C() { raise; } void D () nothrow { //the compiler inferred from body that D cannever throw scope(failure) { writeln("The end of the world"); exit(1); } try { A(); } else try { B(); } else { C(); } }
Jun 02
parent reply Vasileios Anagnostopoulos <fithis2001 gmail.com> writes:
On Friday, 2 June 2017 at 07:33:05 UTC, Vasileios Anagnostopoulos 
wrote:
 On Thursday, 1 June 2017 at 17:03:52 UTC, Ali Çehreli wrote:
 [...]
But still I believe that nothrow should be mandatory if there is no possibility for a function to throw something. I understand that in the DLL/LIB level this is not possible. However, at least in the .di level it should be there. And if you want my two cents, after reading a lot I came to the "personal" conclusion that Exception objects are wrong. For me it is enough to have something like void A() { raise; } void B() { raise; } void C() { raise; } void D () nothrow { //the compiler inferred from body that D cannever throw scope(failure) { writeln("The end of the world"); exit(1); } try { A(); } else try { B(); } else { C(); } }
Or simply void A() { raise; } void B() nothrow { } void D () nothrow { //the compiler inferred from body that D cannever throw try { A(); } else { B(); } }
Jun 02
parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 06/02/2017 12:35 AM, Vasileios Anagnostopoulos wrote:
 On Friday, 2 June 2017 at 07:33:05 UTC, Vasileios Anagnostopoulos wrote:
 But still I believe that  nothrow should be mandatory if there is no
 possibility for a function to throw something. I understand that in
 the DLL/LIB level this is not possible. However, at least in the .di
 level it should be there.

 And if you want my two cents, after reading a lot I came to the
 "personal" conclusion that Exception objects are wrong. For me it is
 enough to have something like
 Or simply

 void A() {
  raise;
 }

 void B() nothrow {
 }


 void D () nothrow { //the compiler inferred from body that D cannever 
throw
 try {
  A();
 } else {
   B();
 }

 }
If I understand you correctly, you want the compiler to force the programmer to be explicit about nothrow. That's an interesting idea... I don't have strong opinions on the matter. To add to this discussion, there is the "Checked vs unchecked exceptions" thread currently active on the general newsgroup: http://forum.dlang.org/post/hxhjcchsulqejwxywfbn forum.dlang.org Ali
Jul 05
prev sibling next sibling parent reply Jonathan M Davis via Digitalmars-d-learn writes:
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
next sibling parent Vasileios Anagnostopoulos <fithis2001 gmail.com> writes:
On Wednesday, 31 May 2017 at 09:31:48 UTC, Jonathan M Davis wrote:
 [...]
Thank you for the answers.
May 31
prev sibling parent Yuxuan Shui <yshuiv7 gmail.com> writes:
On Wednesday, 31 May 2017 at 09:31:48 UTC, Jonathan M Davis wrote:
 On Wednesday, May 31, 2017 08:18:07 Vasileios Anagnostopoulos 
 via Digitalmars-d-learn wrote:
 [...]
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.
I don't think this is possible in current D? nothrow functions can still throw Error.
Jul 05
prev sibling parent Yuxuan Shui <yshuiv7 gmail.com> writes:
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?
Adding throws to a function requires changing all the functions downstream. Adding nothrow doesn't.
Jul 05