digitalmars.D.bugs - AssertError on missing return?
- J C Calvarese (18/18) Aug 23 2004 I think I found a bug. I could be wrong. ;)
- Ivan Senji (16/34) Aug 23 2004 This is expected behaviour, and was discussed before.
- Matthew (4/41) Aug 24 2004 If D's simpler than C++ to implement, and C++ compilers can do this pret...
- Ivan Senji (15/61) Aug 25 2004 news:cgemi7$e6i$1@digitaldaemon.com...
- Walter (10/11) Aug 25 2004 much in their sleep, then why should D not?
- Arcane Jill (24/29) Aug 25 2004 I'd rather have it that way round that the current way round. False posi...
- Walter (22/50) Aug 25 2004 positives
- Arcane Jill (6/13) Aug 26 2004 I could always write:
- Walter (5/9) Aug 26 2004 Yes, you could always write a comment. The trouble with comments, though...
- Martin M. Pedersen (11/14) Aug 26 2004 is
- Walter (9/21) Aug 29 2004 though,
- Matthew (8/19) Aug 25 2004 Well it's the "completely" that's the issue. I don't need 100%. In the c...
- Arcane Jill (5/7) Aug 25 2004 It's /much/ worse than that if you compile with the "-release" flag. The...
- Walter (21/27) Aug 25 2004 the
- Walter (25/30) Aug 25 2004 result
- Sean Kelly (18/48) Aug 25 2004 I think the difference of opinion here has to do with expectations. You...
- Matthew (8/36) Aug 25 2004 I completely agree that having the program fail if its in an invalid sta...
- Regan Heath (14/69) Aug 25 2004 I agree with Matthew here.
- Walter (11/18) Aug 26 2004 is preferable to soldiering on. Absolutely
- Matthew (6/25) Aug 26 2004 I've never had to insert one. I've always been able to sensibly reorder ...
- Arcane Jill (5/8) Aug 26 2004 Matthew's idea is better than mine. I support it. Let's do this. If exec...
- Walter (25/35) Aug 26 2004 news:cgk28d$3i$1@digitaldaemon.com...
- Matthew (9/47) Aug 26 2004 You don't see the difference between
- Arcane Jill (26/35) Aug 26 2004 You're completely missing the point. Your statement above is obviously t...
- Ivan Senji (21/56) Aug 26 2004 terms
- Walter (9/20) Aug 26 2004 true, and
- Ivan Senji (29/52) Aug 26 2004 what
- stonecobra (8/12) Aug 26 2004 You mean writing superfluous return statements like this:
-
Arcane Jill
(4/17)
Aug 26 2004
In article
, stonecobra says... - Andy Friesen (26/61) Aug 26 2004 Microsoft's C# compiler handles this easily enough, but fails if the
- Arcane Jill (13/15) Aug 26 2004 Almost. But
- Dave (39/62) Aug 26 2004 Ok, so here's how I understand the debate so far:
- Arcane Jill (30/45) Aug 26 2004 It's not actually a large amount of effort. Basically, wherever you have...
- Dave (18/39) Aug 26 2004 Perhaps it isn't a huge effort, but I suspect that adding another check ...
- Andy Friesen (7/29) Aug 26 2004 Maybe, as a special case, assert(false) should stick around even in
- Sean Kelly (5/13) Aug 26 2004 I think it is. Though I'd prefer an assert to an exception in debug bui...
- Matthew (2/8) Aug 25 2004 Bah! This just sucks then. Count me a seconder to your objections.
- Regan Heath (16/50) Aug 25 2004 This is your opinion Matthew, you're entitled to it. I think you're bein...
- Dave (13/27) Aug 25 2004 I agree that this runtime check is nice to have for debug builds regardl...
- Ivan Senji (15/26) Aug 25 2004 pretty
- J C Calvarese (11/22) Aug 25 2004 I wasn't trying to get into this debate. It's already been debated and I...
- Walter (7/13) Aug 25 2004 than:
- Derek Parnell (31/50) Aug 25 2004 Yes, a better message would be nice. Maybe "'return' expected but none w...
- Walter (5/22) Aug 26 2004 for
I think I found a bug. I could be wrong. ;) bit b; int main() { if (b) return 0; } Note the lack of a return statement when b is false (which is always). It compiles fine. At runtime, an error occurs... Error: AssertError Failure bug.d(7) I understand it can be difficult/undesirable for the compiler to catch a problem like this during compile. If the lack of a return is cause of the AssertError, I hope it could at least be renamed to NoReturnError or something. (I've observed this with DMD 0.98 and DMD 0.100 on WinXP.) -- Justin (a/k/a jcc7) http://jcc_7.tripod.com/d/
Aug 23 2004
"J C Calvarese" <jcc7 cox.net> wrote in message news:cge2ru$4gs$1 digitaldaemon.com...I think I found a bug. I could be wrong. ;) bit b; int main() { if (b) return 0; } Note the lack of a return statement when b is false (which is always). It compiles fine. At runtime, an error occurs... Error: AssertError Failure bug.d(7)This is expected behaviour, and was discussed before. Some people argued that compiler should check that every code path ends in return or throw and i think Walter said it was too complicated. The only requirement now is that function has at least one return statement, so you can trick compiler to do bad things easilly: int func() { goto skipret; return 0; skipret:; } As far as compiler is consearned this is a valid func(even though return isn't reachable), but will also get you AssertError :(I understand it can be difficult/undesirable for the compiler to catch a problem like this during compile. If the lack of a return is cause of the AssertError, I hope it could at least be renamed to NoReturnError or something. (I've observed this with DMD 0.98 and DMD 0.100 on WinXP.) -- Justin (a/k/a jcc7) http://jcc_7.tripod.com/d/
Aug 23 2004
"Ivan Senji" <ivan.senji public.srce.hr> wrote in message news:cgemi7$e6i$1 digitaldaemon.com..."J C Calvarese" <jcc7 cox.net> wrote in message news:cge2ru$4gs$1 digitaldaemon.com...If D's simpler than C++ to implement, and C++ compilers can do this pretty much in their sleep, then why should D not? IMO, it's ridiculous that code such asI think I found a bug. I could be wrong. ;) bit b; int main() { if (b) return 0; } Note the lack of a return statement when b is false (which is always). It compiles fine. At runtime, an error occurs... Error: AssertError Failure bug.d(7)This is expected behaviour, and was discussed before. Some people argued that compiler should check that every code path ends in return or throw and i think Walter said it was too complicated. The only requirement now is that function has at least one return statement, so you can trick compiler to do bad things easilly: int func() { goto skipret; return 0; skipret:; } As far as compiler is consearned this is a valid func(even though return isn't reachable), but will also get you AssertError :(can get past the compiler. Period.bit b; int main() { if (b) return 0; }
Aug 24 2004
"Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message news:cgh9ms$1ohc$1 digitaldaemon.com..."Ivan Senji" <ivan.senji public.srce.hr> wrote in messagenews:cgemi7$e6i$1 digitaldaemon.com...much in their sleep, then why should D not? You are absoulutelly right. And the problem is i can't see a problem in implementing it: bool statementListEndsInReturn(StatementList sl) { if(typeid(sl.laststatement) === typeid(ReturnStatement))return true; if(typeid(sl.laststatement) === typeid(IfStatement)) return statementListEndsInReturn(sl.laststatement.truepart) && statementListEndsInReturn(sl.laststatement.elsepart); //maybe a couple of more cases return false; }"J C Calvarese" <jcc7 cox.net> wrote in message news:cge2ru$4gs$1 digitaldaemon.com...If D's simpler than C++ to implement, and C++ compilers can do this prettyI think I found a bug. I could be wrong. ;) bit b; int main() { if (b) return 0; } Note the lack of a return statement when b is false (which is always). It compiles fine. At runtime, an error occurs... Error: AssertError Failure bug.d(7)This is expected behaviour, and was discussed before. Some people argued that compiler should check that every code path ends in return or throw and i think Walter said it was too complicated. The only requirement now is that function has at least one return statement, so you can trick compiler to do bad things easilly: int func() { goto skipret; return 0; skipret:; } As far as compiler is consearned this is a valid func(even though return isn't reachable), but will also get you AssertError :(IMO, it's ridiculous that code such ascan get past the compiler. Period.bit b; int main() { if (b) return 0; }
Aug 25 2004
"Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message news:cgh9ms$1ohc$1 digitaldaemon.com...If D's simpler than C++ to implement, and C++ compilers can do this prettymuch in their sleep, then why should D not? I've never seen a C++ compiler get it completely right, and there's no way that they can. I don't like putting in meaningless return statements in code that will never be executed and that will confuse the maintenance programmer, just to get the compiler to stop issuing an error message. But I do want to find out if that meaningless return statement ever does happen. There's no way to do it 100% without a runtime check, hence that's what the language does.
Aug 25 2004
In article <cghkuj$1uni$1 digitaldaemon.com>, Walter says...I don't like putting in meaningless return statements in code that will never be executed and that will confuse the maintenance programmer, just to get the compiler to stop issuing an error message.I'd rather have it that way round that the current way round. False positives (unnecessary returns) are better than false negatives (failing to reach a return at all) in this situation. Consider: So the compiler demands a superfluous return. Big deal. I can live with that. Better a statement which won't get executed (and therefore won't affect the running of my program in any way at all) than a run-time assert in a debug build and a crash in a release build.But I do want to find out if that meaningless return statement ever does happen. There's no way to do it 100% without a runtime check,Yes. No-one's arguing with that. I just don't think it that important. I'd rather have a compiler which claimed that good code is bad, than a compiler which claimed that bad code is good. I've had crashes because of this situation, and I'd rather not have any more. Arcane Jill
Aug 25 2004
"Arcane Jill" <Arcane_member pathlink.com> wrote in message news:cghqva$211l$1 digitaldaemon.com...In article <cghkuj$1uni$1 digitaldaemon.com>, Walter says...positivesI don't like putting in meaningless return statements in code that will never be executed and that will confuse the maintenance programmer, just to get the compiler to stop issuing an error message.I'd rather have it that way round that the current way round. False(unnecessary returns) are better than false negatives (failing to reach areturnat all) in this situation. Consider: So the compiler demands a superfluous return. Big deal. I can live withthat.Better a statement which won't get executed (and therefore won't affecttherunning of my program in any way at all) than a run-time assert in a debugbuildand a crash in a release build.I disagree strongly. When I am maintaining/reviewing code, every statement must be justified. If I see a superfluous "return 0;", I'll look at all the callers to make sure they can handle a 0 value. If they can't, it isn't clear at all that they don't need to. I like to be able to look at code and know that "this cannot happen". And if the superfluous return *does* get executed because of a different bug, now you've got a garbage return value that's seeped into your data, possibly corrupting things in unpredictable ways. I cannot see how this is superior. With the assert, you get an *unambiguous indication* of a bug in your program. I pick an unambiguous and repeatable indication of an error every time over a bad value sneaking unobserved into my data.compilerBut I do want to find out if that meaningless return statement ever does happen. There's no way to do it 100% without a runtime check,Yes. No-one's arguing with that. I just don't think it that important. I'd rather have a compiler which claimed that good code is bad, than awhich claimed that bad code is good. I've had crashes because of thissituation,and I'd rather not have any more.Putting in a superfluous return isn't going to help you find those kind of bugs. It will just paper it over.
Aug 25 2004
In article <cgiq4b$2f6o$1 digitaldaemon.com>, Walter says...I disagree strongly. When I am maintaining/reviewing code, every statement must be justified. If I see a superfluous "return 0;", I'll look at all the callers to make sure they can handle a 0 value. If they can't, it isn't clear at all that they don't need to. I like to be able to look at code and know that "this cannot happen". And if the superfluous return *does* get executed because of a different bug, now you've got a garbage return value that's seeped into your data,I could always write: instead of: Jill
Aug 26 2004
"Arcane Jill" <Arcane_member pathlink.com> wrote in message news:cgk4g7$24i$1 digitaldaemon.com...I could always write: instead of:Yes, you could always write a comment. The trouble with comments, though, is they are always wrong, out of date, or missing. When examining code, I prefer to rely on the semantics of the language <g>.
Aug 26 2004
"Walter" <newshound digitalmars.com> skrev i en meddelelse news:cgka7p$4c2$1 digitaldaemon.com...Yes, you could always write a comment. The trouble with comments, though,isthey are always wrong, out of date, or missing. When examining code, I prefer to rely on the semantics of the language <g>.Perhaps it would help if we had some construct that told both the fellow-programmer and the compiler, that it is an error if the program flow ever reached that point. assert(0) is traditionally used, but it is only good in debug builds. If we had a specialized construct, it would allow the compiler to perform optimizations on that basis, and we would have a way to make the compiler keep quiet about missing return values. Regards, Martin
Aug 26 2004
"Martin M. Pedersen" <martin moeller-pedersen.dk> wrote in message news:cglq6t$sad$1 digitaldaemon.com..."Walter" <newshound digitalmars.com> skrev i en meddelelse news:cgka7p$4c2$1 digitaldaemon.com...though,Yes, you could always write a comment. The trouble with comments,isflowthey are always wrong, out of date, or missing. When examining code, I prefer to rely on the semantics of the language <g>.Perhaps it would help if we had some construct that told both the fellow-programmer and the compiler, that it is an error if the programever reached that point. assert(0) is traditionally used, but it is only good in debug builds. If we had a specialized construct, it would allowthecompiler to perform optimizations on that basis, and we would have a waytomake the compiler keep quiet about missing return values.That could be done, and is what Matthew proposed. But I don't see this as a big enough problem to justify adding a new keyword. Having the exception generated if one does erroneously run off the end is sufficient.
Aug 29 2004
"Walter" <newshound digitalmars.com> wrote in message news:cghkuj$1uni$1 digitaldaemon.com..."Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message news:cgh9ms$1ohc$1 digitaldaemon.com...Well it's the "completely" that's the issue. I don't need 100%. In the code I write, I've maybe come across the C++ compiler not spot a missing return only a handful of types in 12 years. Conversely, I've had false positives perhaps 5 or six times a year. Frankly, I'd rather have that than missing a return. I'd far rather have the slight inconvenience of having to workaround a false positive 5 times a year than the unquantifiable and unpredictable throwing of exceptions at any time after the deployment of my code. Frankly, this is another of those situations where your penchant for compiler simplicity and the influence of your own coding style are given precedence over measures of robustness and scalability to, IMO, the long-term detriment of the language.If D's simpler than C++ to implement, and C++ compilers can do this prettymuch in their sleep, then why should D not? I've never seen a C++ compiler get it completely right, and there's no way that they can. I don't like putting in meaningless return statements in code that will never be executed and that will confuse the maintenance programmer, just to get the compiler to stop issuing an error message. But I do want to find out if that meaningless return statement ever does happen. There's no way to do it 100% without a runtime check, hence that's what the language does.
Aug 25 2004
In article <cght30$21u3$1 digitaldaemon.com>, Matthew says...unquantifiable and unpredictable throwing of exceptions at any time after the deployment of my code.It's /much/ worse than that if you compile with the "-release" flag. These are asserts, not exceptions. They vanish in a release build, leaving you with /seriously/ undefined behavior. Arcane Jill
Aug 25 2004
"Arcane Jill" <Arcane_member pathlink.com> wrote in message news:cgi05f$234t$1 digitaldaemon.com...In article <cght30$21u3$1 digitaldaemon.com>, Matthew says...theunquantifiable and unpredictable throwing of exceptions at any time afterThey are not any more unpredictable than any other bugs in your program - and at least you have a chance of finding this bug before release. The superfluous return has proveably *less* chance of being found before release.deployment of my code.It's /much/ worse than that if you compile with the "-release" flag. Theseareasserts, not exceptions. They vanish in a release build, leaving you with /seriously/ undefined behavior.Yet executing a superfluous return that returns a value that was never intended to be returned is an easier to find bug? I don't see how. I'd *much* rather have the assert. The principle here is that, as much as practical, program bugs should result in the program stopping immediately upon detection and issuing some appropriate error message. Trying to soldier on with some arbitrary return value will just cause your program to fail somewhere else in a far more obscure manner. This discussion reminds me of an old joke about assembler programming: ... various assembler instructions ... HALT ; stop program HALT ; if skidding HALT ; needed if program was running really, really fast
Aug 25 2004
"Walter" <newshound digitalmars.com> wrote in message news:cgirt4$2fvp$1 digitaldaemon.com...The principle here is that, as much as practical, program bugs shouldresultin the program stopping immediately upon detection and issuing some appropriate error message. Trying to soldier on with some arbitrary return value will just cause your program to fail somewhere else in a far more obscure manner.Let me expand on that a bit, because I feel strongly about this. The idea in developing robust code is to flush out bugs by making the program with the bug in it fail quickly and obviously. Inadvertantly executing statements that were never intended to be executed will likely hide bugs, making them hard to detect and harder to track down. In addition, having an assert for the missing return means that, if you run the test suite and no assert happens, you KNOW that the missing return is not executed. But if you've installed a superfluous return there, then there is NO WAY to know that the return was not executed. If you're concerned that your test suite is inadequate and your release code is therefore still buggy, and removing all the runtime checks like array bounds checking and missing return asserts will thereby cause erratic behavior, your best course of action is to leave the checks in in the shipping code. Trying to pretend the bugs aren't there by putting in superfluous code is not going to help make the released program more reliable and less buggy. As a further point, some QA processes involve instrumenting code to verify that every code path was executed by the test suite. Being forced to put in superfluous, unreachable statements throws a monkey wrench into that methodology. (One of my first major projects used such a tool, it was also probably the least buggy code I've ever done as a result. Perhaps I should add this capability to D!)
Aug 25 2004
In article <cgj749$2kt7$1 digitaldaemon.com>, Walter says..."Walter" <newshound digitalmars.com> wrote in message news:cgirt4$2fvp$1 digitaldaemon.com...I think the difference of opinion here has to do with expectations. Your way seems to expect programmers to know exactly what they're doing and to be able to test their applications fairly thoroughly for errors. The other way seems to expect that the programmer may make dumb mistakes and would like the compiler to offer more support in finding those mistakes, even though this may occasionally lead to a false sense of security.The principle here is that, as much as practical, program bugs shouldresultin the program stopping immediately upon detection and issuing some appropriate error message. Trying to soldier on with some arbitrary return value will just cause your program to fail somewhere else in a far more obscure manner.Let me expand on that a bit, because I feel strongly about this. The idea in developing robust code is to flush out bugs by making the program with the bug in it fail quickly and obviously. Inadvertantly executing statements that were never intended to be executed will likely hide bugs, making them hard to detect and harder to track down. In addition, having an assert for the missing return means that, if you run the test suite and no assert happens, you KNOW that the missing return is not executed. But if you've installed a superfluous return there, then there is NO WAY to know that the return was not executed.If you're concerned that your test suite is inadequate and your release code is therefore still buggy, and removing all the runtime checks like array bounds checking and missing return asserts will thereby cause erratic behavior, your best course of action is to leave the checks in in the shipping code. Trying to pretend the bugs aren't there by putting in superfluous code is not going to help make the released program more reliable and less buggy.Overall, I think your approach is more in-line with the D rationale (imagine that ;). I think it also implies that D is not a beginner's language despite its straightforward syntax, or perhaps merely that proper use of D really requires programming and testing practices not common to beginners. In some respects this makes me wish I were a CS teacher as I would be interested in seeing how folks turned out if they were taught D as a first or second language.As a further point, some QA processes involve instrumenting code to verify that every code path was executed by the test suite. Being forced to put in superfluous, unreachable statements throws a monkey wrench into that methodology. (One of my first major projects used such a tool, it was also probably the least buggy code I've ever done as a result. Perhaps I should add this capability to D!)If you could do it then please do so. D's built-in support for DBC and unit testing are substantial reasons why I initially became interested in the language. If D had even more features in the testing realm it could only strengthen this selling point. Sean
Aug 25 2004
"Walter" <newshound digitalmars.com> wrote in message news:cgirt4$2fvp$1 digitaldaemon.com..."Arcane Jill" <Arcane_member pathlink.com> wrote in message news:cgi05f$234t$1 digitaldaemon.com...I completely agree that having the program fail if its in an invalid state is preferable to soldiering on. Absolutely completely agree with that. But I also prefer *in every conceivable circumstance* to have the compile refuse to compile than insert a runtime check. To me these things are completely different, and one should not be mixed with the other. Since C++ is able to, in almost all cases, find it at compile time, then I fail to see why D shouldn't. I accept that neither C++ nor D can find every one, in which case I prefer the assert to arbitrary behaviour. But "we can't find 100% at compile time" is no justification for "we won't look for *any* at compile time".In article <cght30$21u3$1 digitaldaemon.com>, Matthew says...theunquantifiable and unpredictable throwing of exceptions at any time afterThey are not any more unpredictable than any other bugs in your program - and at least you have a chance of finding this bug before release. The superfluous return has proveably *less* chance of being found before release.deployment of my code.It's /much/ worse than that if you compile with the "-release" flag. Theseareasserts, not exceptions. They vanish in a release build, leaving you with /seriously/ undefined behavior.Yet executing a superfluous return that returns a value that was never intended to be returned is an easier to find bug? I don't see how. I'd *much* rather have the assert. The principle here is that, as much as practical, program bugs should result in the program stopping immediately upon detection and issuing some appropriate error message. Trying to soldier on with some arbitrary return value will just cause your program to fail somewhere else in a far more obscure manner. This discussion reminds me of an old joke about assembler programming: ... various assembler instructions ... HALT ; stop program HALT ; if skidding HALT ; needed if program was running really, really fast
Aug 25 2004
On Thu, 26 Aug 2004 11:34:15 +1000, Matthew <admin.hat stlsoft.dot.org> wrote:"Walter" <newshound digitalmars.com> wrote in message news:cgirt4$2fvp$1 digitaldaemon.com...I agree with Matthew here. I an ideal world all sources of bugs would be caught at the compile step. Failing that, they should be caught at runtime, causing an exception which reports to the user the location of the fault. In a debug build this could be the file and line number, in release 'Dave's suggestion might be workable (I don't know enough to comment on it). It seems to me that we all agree on the principle but not the implementation, are the compile time checks worth the effort involved in adding them? Matthew says "yes", I agree.. what do you think Walter? Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/"Arcane Jill" <Arcane_member pathlink.com> wrote in message news:cgi05f$234t$1 digitaldaemon.com...I completely agree that having the program fail if its in an invalid state is preferable to soldiering on. Absolutely completely agree with that. But I also prefer *in every conceivable circumstance* to have the compile refuse to compile than insert a runtime check. To me these things are completely different, and one should not be mixed with the other. Since C++ is able to, in almost all cases, find it at compile time, then I fail to see why D shouldn't. I accept that neither C++ nor D can find every one, in which case I prefer the assert to arbitrary behaviour. But "we can't find 100% at compile time" is no justification for "we won't look for *any* at compile time".In article <cght30$21u3$1 digitaldaemon.com>, Matthew says...after theunquantifiable and unpredictable throwing of exceptions at any timeThey are not any more unpredictable than any other bugs in your program - and at least you have a chance of finding this bug before release. The superfluous return has proveably *less* chance of being found before release.deployment of my code.It's /much/ worse than that if you compile with the "-release" flag.These areasserts, not exceptions. They vanish in a release build, leaving youwith/seriously/ undefined behavior.Yet executing a superfluous return that returns a value that was never intended to be returned is an easier to find bug? I don't see how. I'd *much* rather have the assert. The principle here is that, as much as practical, program bugs should result in the program stopping immediately upon detection and issuing some appropriate error message. Trying to soldier on with some arbitrary return value will just cause your program to fail somewhere else in a far more obscure manner. This discussion reminds me of an old joke about assembler programming: ... various assembler instructions ... HALT ; stop program HALT ; if skidding HALT ; needed if program was running really, really fast
Aug 25 2004
"Matthew" <admin.hat stlsoft.dot.org> wrote in message news:cgjf0g$2o40$1 digitaldaemon.com...I completely agree that having the program fail if its in an invalid stateis preferable to soldiering on. Absolutelycompletely agree with that. But I also prefer *in every conceivable circumstance* to have the compilerefuse to compile than insert a runtime check.To me these things are completely different, and one should not be mixedwith the other. Since C++ is able to, in almostall cases, find it at compile time, then I fail to see why D shouldn't. Iaccept that neither C++ nor D can find everyone, in which case I prefer the assert to arbitrary behaviour. But "wecan't find 100% at compile time" is nojustification for "we won't look for *any* at compile time".But the compiler requiring a superfluous return statement is not finding a bug nor is it helping find a bug. It is, often enough, hiding a bug. I've often had to insert such superfluous returns to satisfy various C++ compilers.
Aug 26 2004
"Walter" <newshound digitalmars.com> wrote in message news:cgk28d$3i$1 digitaldaemon.com..."Matthew" <admin.hat stlsoft.dot.org> wrote in message news:cgjf0g$2o40$1 digitaldaemon.com...I've never had to insert one. I've always been able to sensibly reorder the code such that the return was both natural and valid. In such cases, why not have a "noreturn" keyword which would both serve to suppress the compiler's eagerness, and be an *explicit* documentation of the assertion/exception throw point that such a keyword would cause? AFAICS, that's the best of all worlds, and everyone's happy. No?I completely agree that having the program fail if its in an invalid stateis preferable to soldiering on. Absolutelycompletely agree with that. But I also prefer *in every conceivable circumstance* to have the compilerefuse to compile than insert a runtime check.To me these things are completely different, and one should not be mixedwith the other. Since C++ is able to, in almostall cases, find it at compile time, then I fail to see why D shouldn't. Iaccept that neither C++ nor D can find everyone, in which case I prefer the assert to arbitrary behaviour. But "wecan't find 100% at compile time" is nojustification for "we won't look for *any* at compile time".But the compiler requiring a superfluous return statement is not finding a bug nor is it helping find a bug. It is, often enough, hiding a bug. I've often had to insert such superfluous returns to satisfy various C++ compilers.
Aug 26 2004
In article <cgk46j$209$3 digitaldaemon.com>, Matthew says...In such cases, why not have a "noreturn" keyword which would both serve to suppress the compiler's eagerness, and be an *explicit* documentation of the assertion/exception throw point that such a keyword would cause? AFAICS, that's the best of all worlds, and everyone's happy. No?Matthew's idea is better than mine. I support it. Let's do this. If executed, "noreturn" would be almost exactly equivalent to "throw new Error()", indicating a software error - i.e. bug. Arcane Jill
Aug 26 2004
"Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message news:cgk46j$209$3 digitaldaemon.com..."Walter" <newshound digitalmars.com> wrote in messagenews:cgk28d$3i$1 digitaldaemon.com...aBut the compiler requiring a superfluous return statement is not findingI'vebug nor is it helping find a bug. It is, often enough, hiding a bug.the code such that the return was both naturaloften had to insert such superfluous returns to satisfy various C++ compilers.I've never had to insert one. I've always been able to sensibly reorderand valid.I've had to insert them for things like: int func() { while (1) { ... if (condition) return value; ... } }In such cases, why not have a "noreturn" keyword which would both serve tosuppress the compiler's eagerness, and be an*explicit* documentation of the assertion/exception throw point that sucha keyword would cause?AFAICS, that's the best of all worlds, and everyone's happy. No?I don't understand why a thrown exception with an appropriate message is such an anathema. They're good things, they tell you in no uncertain terms that there's a bug in the program, and where that bug is. The noreturn keyword would be redundant - a closing } without a return exp; for a value returning function implicitly specifies that it's an error to fall off the end. All the language does is make such errors impossible to overlook. If the assert message is "NoReturnException file foo.d line 1234", isn't that plenty?
Aug 26 2004
"Walter" <newshound digitalmars.com> wrote in message news:cgkaql$4gq$1 digitaldaemon.com..."Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message news:cgk46j$209$3 digitaldaemon.com...You don't see the difference between - a hidden, implicit insertion of an exception throw that may or may not ever happen, and which is not (easily) amenable to code review, and not at all instrumentable - an overt, instrumentable, expression on the part of the code's author that indicates his/her expressed intention that no return is expected (by his/her design) and that he/she is asking for an overt, explicit insertion of an exception throw that may or may not ever happen ? Really? If so, I give up, as I cannot conceive of any better way of putting it. It seems plainer than the nose on my face to me."Walter" <newshound digitalmars.com> wrote in messagenews:cgk28d$3i$1 digitaldaemon.com...aBut the compiler requiring a superfluous return statement is not findingI'vebug nor is it helping find a bug. It is, often enough, hiding a bug.the code such that the return was both naturaloften had to insert such superfluous returns to satisfy various C++ compilers.I've never had to insert one. I've always been able to sensibly reorderand valid.I've had to insert them for things like: int func() { while (1) { ... if (condition) return value; ... } }In such cases, why not have a "noreturn" keyword which would both serve tosuppress the compiler's eagerness, and be an*explicit* documentation of the assertion/exception throw point that sucha keyword would cause?AFAICS, that's the best of all worlds, and everyone's happy. No?I don't understand why a thrown exception with an appropriate message is such an anathema. They're good things, they tell you in no uncertain terms that there's a bug in the program, and where that bug is. The noreturn keyword would be redundant - a closing } without a return exp; for a value returning function implicitly specifies that it's an error to fall off the end. All the language does is make such errors impossible to overlook. If the assert message is "NoReturnException file foo.d line 1234", isn't that plenty?
Aug 26 2004
In article <cgkaql$4gq$1 digitaldaemon.com>, Walter says...I don't understand why a thrown exception with an appropriate message is such an anathema. They're good things, they tell you in no uncertain terms that there's a bug in the program, and where that bug is.You're completely missing the point. Your statement above is obviously true, and no-one is disagreeing with you. All you're doing is stating the obvious. But it's irrelevant, so I can only assume that you're just not /getting/ what we're complaining about. THIS SHOULD NOT COMPILE: I want the error reported /at compile time/, not at run-time. I want the compiler to tell me "not all execution paths return a value" /at compile time/. And if the way to make the compile-error go away is to change the code to: Then what is wrong with that? Furthermore, it should be a compile-time error to place any code after "return", "noreturn", "throw", "goto" or "break", unless there's a label or a right-brace. The error message should be "Unreachable code at file xxxx line xxxx".The noreturn keyword would be redundant - a closing } without a return exp; for a value returning function implicitly specifies that it's an error to fall off the end. All the language does is make such errors impossible to overlook. If the assert message is "NoReturnException file foo.d line 1234", isn't that plenty?The error message is not a problem (although it should be present in release builds, not just debug builds). The problem is that DMD compiles code which should not compile. Arcane Jill
Aug 26 2004
"Arcane Jill" <Arcane_member pathlink.com> wrote in message news:cgkbn8$4pr$1 digitaldaemon.com...In article <cgkaql$4gq$1 digitaldaemon.com>, Walter says...termsI don't understand why a thrown exception with an appropriate message is such an anathema. They're good things, they tell you in no uncertaintrue, andthat there's a bug in the program, and where that bug is.You're completely missing the point. Your statement above is obviouslyno-one is disagreeing with you. All you're doing is stating the obvious.Butit's irrelevant, so I can only assume that you're just not /getting/ whatwe'recomplaining about. THIS SHOULD NOT COMPILE: I want the error reported /at compile time/, not at run-time. I want the compiler to tell me "not all execution paths return a value" /at compiletime/.And if the way to make the compile-error go away is to change the code to:That is exactly what i would like too. Except i would call it unreachable; :) But i could live with noreturn also. Throwing some UnreachableCodeReachedException sure is better then an assert that doesn't even exist in release and we get undefined behaviour.Then what is wrong with that? Furthermore, it should be a compile-timeerror toplace any code after "return", "noreturn", "throw", "goto" or "break",unlessthere's a label or a right-brace. The error message should be "Unreachablecodeat file xxxx line xxxx".valueThe noreturn keyword would be redundant - a closing } without a return exp; for athereturning function implicitly specifies that it's an error to fall offthatend. All the language does is make such errors impossible to overlook. If the assert message is "NoReturnException file foo.d line 1234", isn'treleaseplenty?The error message is not a problem (although it should be present inbuilds, not just debug builds). The problem is that DMD compiles codewhichshould not compile. Arcane Jill
Aug 26 2004
"Arcane Jill" <Arcane_member pathlink.com> wrote in message news:cgkbn8$4pr$1 digitaldaemon.com...You're completely missing the point. Your statement above is obviouslytrue, andno-one is disagreeing with you. All you're doing is stating the obvious.Butit's irrelevant, so I can only assume that you're just not /getting/ whatwe'recomplaining about. THIS SHOULD NOT COMPILE: I want the error reported /at compile time/, not at run-time. I want the compiler to tell me "not all execution paths return a value" /at compiletime/. But it isn't always an error to write such code. Always diagnosing it as an error means that you have to insert superfluous return statements in that will never get executed. I've already pointed out why this is undesirable.
Aug 26 2004
"Walter" <newshound digitalmars.com> wrote in message news:cglfk6$mqk$1 digitaldaemon.com..."Arcane Jill" <Arcane_member pathlink.com> wrote in message news:cgkbn8$4pr$1 digitaldaemon.com...whatYou're completely missing the point. Your statement above is obviouslytrue, andno-one is disagreeing with you. All you're doing is stating the obvious.Butit's irrelevant, so I can only assume that you're just not /getting/we'reancomplaining about. THIS SHOULD NOT COMPILE: I want the error reported /at compile time/, not at run-time. I want the compiler to tell me "not all execution paths return a value" /at compiletime/. But it isn't always an error to write such code. Always diagnosing it aserror means that you have to insert superfluous return statements in that will never get executed. I've already pointed out why this is undesirable.But most of the time it is. Then add noreturn statement that will fit nicelly in the design by contarct story. In a code like this: int f(int n) { if (n == 1) return 1; noreturn; } That noreturn statement would be a contract with wich i am saying: this part of code can't/(must not) be reached. It would also be useful to see this in someone code, it would clearly document the coders intention. For example if i coded int f(int n) { if(n>0)return 1; if(n<0)return -1; noreturn; //=== throw new Exception("Unreachable code reached in f, line ..."); } And looking at this code someone would imidiatelly know my intention that n is either > 0 or <0, and that may even help someone spot a bug for example that n can be 0. With noreturn there are no superfluous returns (wich are ofcourse as undesirable as missing returns) :)
Aug 26 2004
Walter wrote:But it isn't always an error to write such code. Always diagnosing it as an error means that you have to insert superfluous return statements in that will never get executed. I've already pointed out why this is undesirable.You mean writing superfluous return statements like this: int someFunc() { throw new NotYetWrittenException(); return 0; //superfluous? Methinks so. Never Get executed? Absolutely } :) Scott
Aug 26 2004
In article <cgln3i$qqg$1 digitaldaemon.com>, stonecobra says... Nice one! He he he. Several <g>s and a :) Don't you just love consistency! JillWalter wrote:But it isn't always an error to write such code. Always diagnosing it as an error means that you have to insert superfluous return statements in that will never get executed. I've already pointed out why this is undesirable.You mean writing superfluous return statements like this: int someFunc() { throw new NotYetWrittenException(); return 0; //superfluous? Methinks so. Never Get executed? Absolutely } :) Scott
Aug 26 2004
Walter wrote:"Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message news:cgk46j$209$3 digitaldaemon.com...while condition is anything remotely complicated. For instance, this fails to compile: public int thingie() { int q = 0; // while (true) { // OK while (q == q) { // Not OK Console.WriteLine("q={0}", q); if (q == 4) return q; q++; } } This is more than good enough for me. If DMD were to do the same, its users would be forced to stick an "assert(false);" at the end to make the compiler happy, but I think that's fine because it is a bit more than just shutting the compiler up. The explicit annotation is useful to both people and the compiler, and, while the resulting execution flow is identical, the author is forced to be aware of the potential for a fall-off return. There is certainly the possibility that this will be forced on a programmer even when it is clear as day to him that it can never happen, but everything is clear as day when writing the code. It is, after all, the easiest part. Besides, this is exactly what the assert statement is meant for. :) -- andy"Walter" <newshound digitalmars.com> wrote in messagenews:cgk28d$3i$1 digitaldaemon.com...aBut the compiler requiring a superfluous return statement is not findingI'vebug nor is it helping find a bug. It is, often enough, hiding a bug.the code such that the return was both naturaloften had to insert such superfluous returns to satisfy various C++ compilers.I've never had to insert one. I've always been able to sensibly reorderand valid.I've had to insert them for things like: int func() { while (1) { ... if (condition) return value; ... } }
Aug 26 2004
In article <cgktoo$d5c$1 digitaldaemon.com>, Andy Friesen says...If DMD were to do the same, its users would be forced to stick an "assert(false);" at the endAlmost. But is only equivalent to so there is still a release-build control-path which falls straight through. This also needs to be explicitly blocked. Matthew's "noreturn" idea (or perhaps "unreachable", as has also been suggested) should be executed in both debug and non-debug builds, and so is preferable to "assert". Jill
Aug 26 2004
Arcane Jill wrote:In article <cgktoo$d5c$1 digitaldaemon.com>, Andy Friesen says...Ok, so here's how I understand the debate so far: - The compiler would catch every instance where there could be a mssing return code path, or barring that, a large amount of effort is expended to make it as accurate as possible. - The programmer could always find a way to not miss any potential return paths, and make them all meaningful, as well as not have to spend hours rearranging code to do so. Barring that, the programmer can now throw an exception at the bottom of a function and make the exception verbage as meaningful as they want. Then the 'noreturn' idea was introduced: - The compiler would check for 'noreturn' _or_ 'return ...' at the end of all code paths, making the compiler's job a bit more complicated still. - The programmer could always find a way to not miss any potential return paths, and make all paths meaningful, as well as not have to spend hours to do so. Now they would also have the choice to learn about, remember and use the non-descript 'noreturn' instruction instead of just typing a little more to throw an exception that they could make as meaningful as they want. At this point, I don't see the value of 'noreturn' over an implicit exception, because 'noreturn' wouldn't be any more expressive but would require extra compiler and programmer support. IMHO, the problem with expending a bunch of effort for a really accurate compiler is that it may well still miss the hard cases that the programmer missed in the first place (because they were hard) since it cannot be perfect. Plus the effort was expended that could have been used to make the tool better in more meaningful places, not to mention slowing down the compile speed, etc. Besides, the semantic analysis parts of C++ compilers have the advantage of many man-years and dollars worth of development under their belt. Sounds to me like we're getting little or no value for adding complexity to the language and the compiler if we start adding new "exception shortcut keywords" or diligantly try to make the compiler conform to an explicit return path spec. I think Walter is half-way to a solution now.. Halfway being checking obvious cases at compile time and doing implicit asserts for non-release builds, the other half would be implicit exceptions for release builds, _IF_ they don't screw up performance, which I think may be attainable w/o a lot of effort. - DaveIf DMD were to do the same, its users would be forced to stick an "assert(false);" at the endAlmost. But is only equivalent to so there is still a release-build control-path which falls straight through. This also needs to be explicitly blocked. Matthew's "noreturn" idea (or perhaps "unreachable", as has also been suggested) should be executed in both debug and non-debug builds, and so is preferable to "assert". Jill
Aug 26 2004
In article <cgl7d2$fnm$1 digitaldaemon.com>, Dave says...- The compiler would catch every instance where there could be a mssing return code path, or barring that, a large amount of effort is expended to make it as accurate as possible.It's not actually a large amount of effort. Basically, wherever you have an if(), you have to assume that there will be a path of execution for the true case, and a path for the false case. Similarly, whenever you have a switch(), you have to assume that there is a path of execution for every case, including default. Likewise, when you have a while() or a for(), you have to assume that there is a path of execution through the body, and a path which skips the body. And, you have to be aware that code which follows "return", "goto", "throw", etc., is unreachable. That's pretty much it. This approach may generate false positives, which is why Walter doesn't like it. It would mean that the compiler would say "Not all execution paths return" when a human might know otherwise. It depends whether you consider that more of a problem than the current alternative.- The compiler would check for 'noreturn' _or_ 'return ...' at the end of all code paths, making the compiler's job a bit more complicated still.I can't argue with that. But in fact the compiler should (in my opinion, but not Walter's) count "throw" as equivalent to "return", in that it can be used to exit the function. "noreturn" is not very descriptive, I agree, but "unreachable" has been suggested as an alternative. As you say, it would just be syntactic sugar for "throw" with some suitable exception.At this point, I don't see the value of 'noreturn' over an implicit exception, because 'noreturn' wouldn't be any more expressive but would require extra compiler and programmer support.True. Again, it's just syntactic sugar, and it isn't really important. "throw" works for me just as well. Primarily it's Walter's "false negatives are better than false positives" philosophy with which I and others disagree.IMHO, the problem with expending a bunch of effort for a really accurate compiler is that it may well still miss the hard cases that the programmer missed in the first place (because they were hard) since it cannot be perfect.Really accurate is hard, yes. But if you can live with false positives, you can live with a less accurate analysis. As noted above, the simple analysis is not hard.the other half would be implicit exceptions for release builds, _IF_ they don't screw up performance, which I think may be attainable w/o a lot of effort.There is no way that an unreachable throw statement can hurt performance. By definition, if it's unreachable, it will never be executed. Only if there's a bug in the code can execution ever get to that throw statement - and if there's a bug, a throw is not a bad thing. Arcane Jill
Aug 26 2004
Arcane Jill wrote:In article <cgl7d2$fnm$1 digitaldaemon.com>, Dave says...Perhaps it isn't a huge effort, but I suspect that adding another check like this to the recursive decent logic could complicate the compiler to a significant degree, because now the compiler has to keep track of more information for potentially many other recursions into other logical branches in the same function. I guess I just don't know for sure except to say that other much more mature compilers still miss, so I suspect it isn't totally straight forward.- The compiler would catch every instance where there could be a mssing return code path, or barring that, a large amount of effort is expended to make it as accurate as possible.It's not actually a large amount of effort. Basically, wherever you have an if(), you have to assume that there will be a path of execution for the true case, and a path for the false case. Similarly, whenever you have aTrue. Again, it's just syntactic sugar, and it isn't really important. "throw" works for me just as well. Primarily it's Walter's "false negatives are better than false positives" philosophy with which I and others disagree.Personally, I've always felt that bad data is worse than no data... Ah hell, I can see both points here.There is no way that an unreachable throw statement can hurt performance. By definition, if it's unreachable, it will never be executed. Only if there's a bug in the code can execution ever get to that throw statement - and if there's a bug, a throw is not a bad thing.I agree - I don't think it will either, but I threw in the big IF to get the point across that it needs to be implemented efficiently ;) I held out the possibility that it could potentially cause problems. For example, if an implementation might coax the compiler into reserving scarce resources (like registers) for the call to the Exception class Ctor, and then there are the 'code distance' issues that extra code may exacerbate, etc.. I think everything except the extra bloat could be handled w/o causing adverse effects though.Arcane Jill
Aug 26 2004
Arcane Jill wrote:In article <cgktoo$d5c$1 digitaldaemon.com>, Andy Friesen says...Maybe, as a special case, assert(false) should stick around even in release mode. If it should never execute, it's not exactly in a position to cause much runtime overhead. :) Plus it saves us the hassle of setting a keyword aside for such a narrow purpose. -- andyIf DMD were to do the same, its users would be forced to stick an "assert(false);" at the endAlmost. But is only equivalent to so there is still a release-build control-path which falls straight through. This also needs to be explicitly blocked. Matthew's "noreturn" idea (or perhaps "unreachable", as has also been suggested) should be executed in both debug and non-debug builds, and so is preferable to "assert".
Aug 26 2004
In article <cgkaql$4gq$1 digitaldaemon.com>, Walter says...I don't understand why a thrown exception with an appropriate message is such an anathema. They're good things, they tell you in no uncertain terms that there's a bug in the program, and where that bug is. The noreturn keyword would be redundant - a closing } without a return exp; for a value returning function implicitly specifies that it's an error to fall off the end. All the language does is make such errors impossible to overlook. If the assert message is "NoReturnException file foo.d line 1234", isn't that plenty?I think it is. Though I'd prefer an assert to an exception in debug builds because it would simplify debugging of the problem. And if it already works this way then I have no complaints. Sean
Aug 26 2004
"Arcane Jill" <Arcane_member pathlink.com> wrote in message news:cgi05f$234t$1 digitaldaemon.com...In article <cght30$21u3$1 digitaldaemon.com>, Matthew says...Bah! This just sucks then. Count me a seconder to your objections.unquantifiable and unpredictable throwing of exceptions at any time after the deployment of my code.It's /much/ worse than that if you compile with the "-release" flag. These are asserts, not exceptions. They vanish in a release build, leaving you with /seriously/ undefined behavior.
Aug 25 2004
On Wed, 25 Aug 2004 21:27:32 +1000, Matthew <admin.hat stlsoft.dot.org> wrote:"Walter" <newshound digitalmars.com> wrote in message news:cghkuj$1uni$1 digitaldaemon.com..."Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message news:cgh9ms$1ohc$1 digitaldaemon.com...Well it's the "completely" that's the issue. I don't need 100%. In the code I write, I've maybe come across the C++ compiler not spot a missing return only a handful of types in 12 years. Conversely, I've had false positives perhaps 5 or six times a year. Frankly, I'd rather have that than missing a return. I'd far rather have the slight inconvenience of having to workaround a false positive 5 times a year than the unquantifiable and unpredictable throwing of exceptions at any time after the deployment of my code.If D's simpler than C++ to implement, and C++ compilers can do thispretty much in their sleep, then why should D not? I've never seen a C++ compiler get it completely right, and there's no way that they can. I don't like putting in meaningless return statements in code that will never be executed and that will confuse the maintenance programmer, just to get the compiler to stop issuing an error message. But I do want to find out if that meaningless return statement ever does happen. There's no way to do it 100% without a runtime check, hence that's what the language does.Frankly, this is another of those situations where your penchant for compiler simplicity and the influence of your own coding style are given precedence over measures of robustness and scalability to, IMO, the long-term detriment of the language.This is your opinion Matthew, you're entitled to it. I think you're being unfair, Walter has described his position as being _in_ favour of robustness and scalability, you simply disagree that his approach is robust and/or scalable, which is also an opinion you're entitled to. My opinion is that a middle ground could be found that would hopefully please everyone. I think if possible the compiler should catch what it can be 100% certain of at the compile stage, this step can and will improve as Walter finds examples he can catch, code that passes that step should throw an assertion at runtime in a 'debug' build as it currently does. The current behaviour of a 'release' build is ok, I believe. Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Aug 25 2004
In article <opsda9v8065a2sq9 digitalmars.com>, Regan Heath says...This is your opinion Matthew, you're entitled to it. I think you're being unfair, Walter has described his position as being _in_ favour of robustness and scalability, you simply disagree that his approach is robust and/or scalable, which is also an opinion you're entitled to. My opinion is that a middle ground could be found that would hopefully please everyone. I think if possible the compiler should catch what it can be 100% certain of at the compile stage, this step can and will improve as Walter finds examples he can catch, code that passes that step should throw an assertion at runtime in a 'debug' build as it currently does. The current behaviour of a 'release' build is ok, I believe.I agree that this runtime check is nice to have for debug builds regardless of how good a compiler implementation gets at catching missing returns. This may be one of those checks that could be inserted for release builds too, because if the software takes that path /once/ it dies immediately anyhow (unlike an array bounds check in a loop as an obvious example). That way there would be something for a user to report back. Could inline code with a simple message including the mangled method/function name be used for release builds?? If so then unless I'm missing some register or stack allocation issue or somesuch, it likely won't cost any performance _directly_ related to the function call, but will cost in terms of bloat regardless. Just a suggestion.. - DaveRegan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Aug 25 2004
"Walter" <newshound digitalmars.com> wrote in message news:cghkuj$1uni$1 digitaldaemon.com..."Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message news:cgh9ms$1ohc$1 digitaldaemon.com...prettyIf D's simpler than C++ to implement, and C++ compilers can do thismuch in their sleep, then why should D not? I've never seen a C++ compiler get it completely right, and there's no way that they can. I don't like putting in meaningless return statements incodethat will never be executed and that will confuse the maintenance programmer, just to get the compiler to stop issuing an error message.I agree with Matthew and Arcane Jill on this. I will believe you if you say that there are some strange code fragments for wich it is not possible to detect a missing return or throw, but if D could get it right 95% of the time it would be good enough. Test only for the simplest cases with return on the end of the function or return in every branch or every case of the last if or switch and ignore those like in my example where i try to skip return with a goto. (This one can also be detected, if the last statement is empty and the one before it is a label=> error missing return at the end.)But I do want to find out if that meaningless return statement ever does happen. There's no way to do it 100% without a runtime check, hence that's what the language does.
Aug 25 2004
In article <cghkuj$1uni$1 digitaldaemon.com>, Walter says..."Matthew" <admin stlsoft.dot.dot.dot.dot.org> wrote in message news:cgh9ms$1ohc$1 digitaldaemon.com...I wasn't trying to get into this debate. It's already been debated and I agree with your position. I know the compiler isn't psychic and I don't want it second-guessing every branch in my program. I was just hoping that we could have a more descriptive runtime error than: Error: AssertError Failure bug.d(7) Maybe that can't be done. I just thought it was a possibility. (It only took me a few minutes to figure out what the problem was when I ran into it, but it could have taken a lot longer if I had made more changes or had a larger program.) jcc7If D's simpler than C++ to implement, and C++ compilers can do this prettymuch in their sleep, then why should D not? I've never seen a C++ compiler get it completely right, and there's no way that they can. I don't like putting in meaningless return statements in code that will never be executed and that will confuse the maintenance programmer, just to get the compiler to stop issuing an error message. But I do want to find out if that meaningless return statement ever does happen. There's no way to do it 100% without a runtime check, hence that's what the language does.
Aug 25 2004
"J C Calvarese" <jcc7 cox.net> wrote in message news:cgi8mr$26f7$1 digitaldaemon.com...I was just hoping that we could have a more descriptive runtime errorthan:Error: AssertError Failure bug.d(7) Maybe that can't be done. I just thought it was a possibility. (It only took me a few minutes to figure out what the problem was when Iraninto it, but it could have taken a lot longer if I had made more changesor hada larger program.)I agree the message isn't the best, but at least it had the file and line number <g>.
Aug 25 2004
On Mon, 23 Aug 2004 19:41:34 -0500, J C Calvarese wrote:I think I found a bug. I could be wrong. ;) bit b; int main() { if (b) return 0; } Note the lack of a return statement when b is false (which is always). It compiles fine. At runtime, an error occurs... Error: AssertError Failure bug.d(7) I understand it can be difficult/undesirable for the compiler to catch a problem like this during compile. If the lack of a return is cause of the AssertError, I hope it could at least be renamed to NoReturnError or something.Yes, a better message would be nice. Maybe "'return' expected but none was executed.". And I hope this wouldn't disappear in a "-release" build either. But meanwhile ... Should the principle for a compiler be that it tries to detect all potential errors, within practical limits, that could/would otherwise be detected at run time? I don't know the answer to this, so it is not rhetorical. <anecodote> Recently, in some code of mine, I came across an complex 'if/else if' statement, in which I realized the final 'else' condition would never be met. I'd left it for ages without an 'else' clause, but last week, just for a sense of completeness, I coded something like ... else not owned by owner"); I released the code and almost immediately I had users saying that they were getting this weird error message. It turned out that there were at least three different conditions that fell through to the abort code. They were all bugs in code quite distant from this 'else', but until I added this superfluous 'else' code, I never knew about the bugs. (They caused a slow resource leak). So I fixed the bugs but still I've left in the abort code, just in case I've messed up elsewhere. </anecodote> -- Derek Melbourne, Australia 26/Aug/04 10:14:38 AM
Aug 25 2004
"Derek Parnell" <derek psych.ward> wrote in message news:cgjb3l$2mdv$1 digitaldaemon.com...<anecodote> Recently, in some code of mine, I came across an complex 'if/else if' statement, in which I realized the final 'else' condition would never be met. I'd left it for ages without an 'else' clause, but last week, justfora sense of completeness, I coded something like ... else not owned by owner"); I released the code and almost immediately I had users saying that they were getting this weird error message. It turned out that there were at least three different conditions that fell through to the abort code. They were all bugs in code quite distant from this 'else', but until I added this superfluous 'else' code, I never knew about the bugs. (They caused a slow resource leak). So I fixed the bugs but still I've left in the abort code, just in case I've messed up elsewhere. </anecodote>That's just the kind of problem the check at the implicit return is supposed to detect.
Aug 26 2004