digitalmars.D - no return value
- Andrew Fedoniouk (21/21) Mar 15 2005 Following program, being compiled
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (3/19) Mar 15 2005 --anders
- Andrew Fedoniouk (6/27) Mar 15 2005 You are extremely lucky as.
- Regan Heath (9/18) Mar 15 2005 See:
- Andrew Fedoniouk (8/33) Mar 15 2005 Agreed, it is very reasonable.
- Regan Heath (11/49) Mar 15 2005 Yes.
- Charles (7/28) Mar 15 2005 Yea we've been trying to get Walter to make this a compile time error
- Regan Heath (9/48) Mar 15 2005 The problem is not simply whether it's an error or not. It's whether you...
- Charles (7/62) Mar 15 2005 You mean for the no return statement ? Im not familiar with compiler
- Regan Heath (10/79) Mar 15 2005 Yes. But...
- Charles (8/90) Mar 17 2005 I would prefer this an error as well :).
- Regan Heath (3/107) Mar 17 2005 An incorrect/false error?
- xs0 (26/32) Mar 16 2005 Well, as far as I am concerned, Walter does have a point, although it
- Andy Friesen (9/49) Mar 16 2005 I think the correct way to "shut the compiler up" in this case is to add...
- Manfred Nowak (10/12) Mar 16 2005 [...]
- Andrew Fedoniouk (15/31) Mar 16 2005 Theoretically such _algorithm_ does exist as each program is just a fini...
- Manfred Nowak (21/30) Mar 16 2005 Agreed, but only because I did not express precisely, what I was
- Andrew Fedoniouk (11/45) Mar 16 2005 As far as I can see Walter is already doing analysis of AST
- Manfred Nowak (19/24) Mar 17 2005 I see at least one reason:
- Thomas Kuehne (14/37) Mar 17 2005 -----BEGIN PGP SIGNED MESSAGE-----
- Manfred Nowak (22/24) Mar 18 2005 Please explain your statement. I do not see any correlation between
- Thomas Kuehne (19/39) Mar 18 2005 -----BEGIN PGP SIGNED MESSAGE-----
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (12/14) Mar 17 2005 I'm not sure that eg. adding a flag variable or using goto is better ?
- Manfred Nowak (36/48) Mar 18 2005 You are right that my argument of increased computational complexity
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (21/49) Mar 18 2005 Yes, you are right in that these refactorings usually swing both ways...
Following program, being compiled in -debug, in runtime ends up with the following: C:\d\test>test.exe Error: AssertError Failure test(8) The source of the problem is in int something() - it does not have renturn value set. IMO, either this code must not compile at all or flag -w (warnings) should be 'on' by default. Andrew. ==test.d================ static int v = 0; int something(int vv) { v = vv; } int main(char[][] args) { something(28); } ==test.d==EOF=============
Mar 15 2005
Andrew Fedoniouk wrote:==test.d================ static int v = 0; int something(int vv) { v = vv; } int main(char[][] args) { something(28); } ==test.d==EOF=============Here's what I get with GDC 0.10:test.d:3: function test.something function expected to return a value of type int test.d:8: function test.main function expected to return a value of type int--anders
Mar 15 2005
You are extremely lucky as. dmd.exe test.d is just silently enjoying compilation of this. Andrew. "Anders F Björklund" <afb algonet.se> wrote in message news:d17m4a$298h$1 digitaldaemon.com...Andrew Fedoniouk wrote:==test.d================ static int v = 0; int something(int vv) { v = vv; } int main(char[][] args) { something(28); } ==test.d==EOF=============Here's what I get with GDC 0.10:test.d:3: function test.something function expected to return a value of type int test.d:8: function test.main function expected to return a value of type int--anders
Mar 15 2005
On Tue, 15 Mar 2005 13:58:10 -0800, Andrew Fedoniouk <news terrainformatica.com> wrote:Following program, being compiled in -debug, in runtime ends up with the following: C:\d\test>test.exe Error: AssertError Failure test(8) The source of the problem is in int something() - it does not have renturn value set. IMO, either this code must not compile at all or flag -w (warnings) should be 'on' by default.See: http://www.digitalmars.com/d/archives/digitalmars/D/bugs/1553.html It's the same/very similar reasoning as the assert in the switch statement. The compier cannot know your intent, throwing the assert forces you to consider your intent and make it clear in the code so as the compiler (and next programmer to look at it) knows for sure what you intend. Regan
Mar 15 2005
The compier cannot know your intent, throwing the assert forces you to consider your intent and make it clear in the code so as the compiler (and next programmer to look at it) knows for sure what you intend.Agreed, it is very reasonable. "no return value" should not be a warning but ruther just an error. Right? As I understand assertion in runtime is sort of atavism at these stage of the compiler. Andrew. "Regan Heath" <regan netwin.co.nz> wrote in message news:opsno9iqp723k2f5 nrage.netwin.co.nz...On Tue, 15 Mar 2005 13:58:10 -0800, Andrew Fedoniouk <news terrainformatica.com> wrote:Following program, being compiled in -debug, in runtime ends up with the following: C:\d\test>test.exe Error: AssertError Failure test(8) The source of the problem is in int something() - it does not have renturn value set. IMO, either this code must not compile at all or flag -w (warnings) should be 'on' by default.See: http://www.digitalmars.com/d/archives/digitalmars/D/bugs/1553.html It's the same/very similar reasoning as the assert in the switch statement. The compier cannot know your intent, throwing the assert forces you to consider your intent and make it clear in the code so as the compiler (and next programmer to look at it) knows for sure what you intend. Regan
Mar 15 2005
On Tue, 15 Mar 2005 14:41:26 -0800, Andrew Fedoniouk <news terrainformatica.com> wrote:Yes.The compier cannot know your intent, throwing the assert forces you to consider your intent and make it clear in the code so as the compiler (and next programmer to look at it) knows for sure what you intend.Agreed, it is very reasonable. "no return value" should not be a warning but ruther just an error. Right?As I understand assertion in runtime is sort of atavism at these stage of the compiler.The runtime assert is given because detecting this at compile time is either very difficult or perhaps impossible in some situations. So, if you were used to it giving an error at compile time, then happened to have one that it could not (or did not yet) detect, you would not know it, and the bug it caused would manifest later in the code, and be hard to track/find. Throwing the assert tells you exactly where and when the bug occured, allowing you to resolve it quickly and easily. Regan"Regan Heath" <regan netwin.co.nz> wrote in message news:opsno9iqp723k2f5 nrage.netwin.co.nz...On Tue, 15 Mar 2005 13:58:10 -0800, Andrew Fedoniouk <news terrainformatica.com> wrote:Following program, being compiled in -debug, in runtime ends up with the following: C:\d\test>test.exe Error: AssertError Failure test(8) The source of the problem is in int something() - it does not have renturn value set. IMO, either this code must not compile at all or flag -w (warnings) should be 'on' by default.See: http://www.digitalmars.com/d/archives/digitalmars/D/bugs/1553.html It's the same/very similar reasoning as the assert in the switch statement. The compier cannot know your intent, throwing the assert forces you to consider your intent and make it clear in the code so as the compiler (and next programmer to look at it) knows for sure what you intend. Regan
Mar 15 2005
Yea we've been trying to get Walter to make this a compile time error forever, he stands alone on the 'shut-up code' argument last I read. Can anyone give me a situation where no return is NOT an error, and therefore should not be caught at compile time ? I'd even go further and say 'not-all control paths return a value' should be a compile time error. "Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:d17lpi$291e$1 digitaldaemon.com...Following program, being compiled in -debug, in runtime ends up with the following: C:\d\test>test.exe Error: AssertError Failure test(8) The source of the problem is in int something() - it does not have renturn value set. IMO, either this code must not compile at all or flag -w (warnings) should be 'on' by default. Andrew. ==test.d================ static int v = 0; int something(int vv) { v = vv; } int main(char[][] args) { something(28); } ==test.d==EOF=============
Mar 15 2005
On Tue, 15 Mar 2005 18:18:36 -0600, Charles <cee-lo green.com> wrote:Yea we've been trying to get Walter to make this a compile time error forever, he stands alone on the 'shut-up code' argument last I read. Can anyone give me a situation where no return is NOT an error, and therefore should not be caught at compile time ? I'd even go further and say 'not-all control paths return a value' should be a compile time error.The problem is not simply whether it's an error or not. It's whether you can correctly detect all cases, and the answer seems to be "no, you cannot", or, "you might be able to but it would take a lot of work to do so". It's true that some C/C++ compilers attempt to, they also give false positives, meaning, when you get one you're not sure if it's a real one, or not. Regan"Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:d17lpi$291e$1 digitaldaemon.com...Following program, being compiled in -debug, in runtime ends up with the following: C:\d\test>test.exe Error: AssertError Failure test(8) The source of the problem is in int something() - it does not have renturn value set. IMO, either this code must not compile at all or flag -w (warnings) should be 'on' by default. Andrew. ==test.d================ static int v = 0; int something(int vv) { v = vv; } int main(char[][] args) { something(28); } ==test.d==EOF=============
Mar 15 2005
The problem is not simply whether it's an error or not. It's whether you can correctly detect all cases, and the answer seems to be "no, you cannot", or, "you might be able to but it would take a lot of work to do so".You mean for the no return statement ? Im not familiar with compiler internals but wouldn't it have to inject an assert there when generating code ? If thats the case then it should be easy to switch to a compile time error maybe ? "Regan Heath" <regan netwin.co.nz> wrote in message news:opsnpibito23k2f5 nrage.netwin.co.nz...On Tue, 15 Mar 2005 18:18:36 -0600, Charles <cee-lo green.com> wrote:andYea we've been trying to get Walter to make this a compile time error forever, he stands alone on the 'shut-up code' argument last I read. Can anyone give me a situation where no return is NOT an error, and therefore should not be caught at compile time ? I'd even go furthersay 'not-all control paths return a value' should be a compile time error.The problem is not simply whether it's an error or not. It's whether you can correctly detect all cases, and the answer seems to be "no, you cannot", or, "you might be able to but it would take a lot of work to do so". It's true that some C/C++ compilers attempt to, they also give false positives, meaning, when you get one you're not sure if it's a real one, or not. Regan"Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:d17lpi$291e$1 digitaldaemon.com...Following program, being compiled in -debug, in runtime ends up with the following: C:\d\test>test.exe Error: AssertError Failure test(8) The source of the problem is in int something() - it does not have renturn value set. IMO, either this code must not compile at all or flag -w (warnings) should be 'on' by default. Andrew. ==test.d================ static int v = 0; int something(int vv) { v = vv; } int main(char[][] args) { something(28); } ==test.d==EOF=============
Mar 15 2005
On Tue, 15 Mar 2005 19:31:54 -0600, Charles <cee-lo green.com> wrote:Yes.The problem is not simply whether it's an error or not. It's whether you can correctly detect all cases, and the answer seems to be "no, you cannot", or, "you might be able to but it would take a lot of work to do so".You mean for the no return statement ?Im not familiar with compiler internals but wouldn't it have to inject an assert there when generating code ?Yes. But... int foo() { if (true) return 5; } the compiler simply injects an assert at the end of this function. We're it to give an error, it would be wrong.If thats the case then it should be easy to switch to a compile time error maybe ?No. Because of false errors, as shown in the example above. Regan"Regan Heath" <regan netwin.co.nz> wrote in message news:opsnpibito23k2f5 nrage.netwin.co.nz...On Tue, 15 Mar 2005 18:18:36 -0600, Charles <cee-lo green.com> wrote:andYea we've been trying to get Walter to make this a compile time error forever, he stands alone on the 'shut-up code' argument last I read. Can anyone give me a situation where no return is NOT an error, and therefore should not be caught at compile time ? I'd even go furthersay 'not-all control paths return a value' should be a compile time error.The problem is not simply whether it's an error or not. It's whether you can correctly detect all cases, and the answer seems to be "no, you cannot", or, "you might be able to but it would take a lot of work to do so". It's true that some C/C++ compilers attempt to, they also give false positives, meaning, when you get one you're not sure if it's a real one, or not. Regan"Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:d17lpi$291e$1 digitaldaemon.com...Following program, being compiled in -debug, in runtime ends up with the following: C:\d\test>test.exe Error: AssertError Failure test(8) The source of the problem is in int something() - it does not have renturn value set. IMO, either this code must not compile at all or flag -w (warnings) should be 'on' by default. Andrew. ==test.d================ static int v = 0; int something(int vv) { v = vv; } int main(char[][] args) { something(28); } ==test.d==EOF=============
Mar 15 2005
I would prefer this an error as well :). "Regan Heath" <regan netwin.co.nz> wrote in message news:opsnpiuwlf23k2f5 nrage.netwin.co.nz...On Tue, 15 Mar 2005 19:31:54 -0600, Charles <cee-lo green.com> wrote:youThe problem is not simply whether it's an error or not. It's whetherdocan correctly detect all cases, and the answer seems to be "no, you cannot", or, "you might be able to but it would take a lot of work toyouYes.so".You mean for the no return statement ?Im not familiar with compiler internals but wouldn't it have to inject an assert there when generating code ?Yes. But... int foo() { if (true) return 5; } the compiler simply injects an assert at the end of this function. We're it to give an error, it would be wrong.If thats the case then it should be easy to switch to a compile time error maybe ?No. Because of false errors, as shown in the example above. Regan"Regan Heath" <regan netwin.co.nz> wrote in message news:opsnpibito23k2f5 nrage.netwin.co.nz...On Tue, 15 Mar 2005 18:18:36 -0600, Charles <cee-lo green.com> wrote:andYea we've been trying to get Walter to make this a compile time error forever, he stands alone on the 'shut-up code' argument last I read. Can anyone give me a situation where no return is NOT an error, and therefore should not be caught at compile time ? I'd even go furthersay 'not-all control paths return a value' should be a compile time error.The problem is not simply whether it's an error or not. It's whetherdocan correctly detect all cases, and the answer seems to be "no, you cannot", or, "you might be able to but it would take a lot of work toone,so". It's true that some C/C++ compilers attempt to, they also give false positives, meaning, when you get one you're not sure if it's a realor not. Regan"Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:d17lpi$291e$1 digitaldaemon.com...Following program, being compiled in -debug, in runtime ends up with the following: C:\d\test>test.exe Error: AssertError Failure test(8) The source of the problem is in int something() - it does not have renturn value set. IMO, either this code must not compile at all or flag -w (warnings) should be 'on' by default. Andrew. ==test.d================ static int v = 0; int something(int vv) { v = vv; } int main(char[][] args) { something(28); } ==test.d==EOF=============
Mar 17 2005
On Thu, 17 Mar 2005 16:36:12 -0600, Charles <cee-lo green.com> wrote:I would prefer this an error as well :).An incorrect/false error? Regan"Regan Heath" <regan netwin.co.nz> wrote in message news:opsnpiuwlf23k2f5 nrage.netwin.co.nz...On Tue, 15 Mar 2005 19:31:54 -0600, Charles <cee-lo green.com> wrote:youThe problem is not simply whether it's an error or not. It's whetherdocan correctly detect all cases, and the answer seems to be "no, you cannot", or, "you might be able to but it would take a lot of work toyouYes.so".You mean for the no return statement ?Im not familiar with compiler internals but wouldn't it have to inject an assert there whengeneratingcode ?Yes. But... int foo() { if (true) return 5; } the compiler simply injects an assert at the end of this function. We're it to give an error, it would be wrong.If thats the case then it should be easy to switch to a compile time error maybe ?No. Because of false errors, as shown in the example above. Regan"Regan Heath" <regan netwin.co.nz> wrote in message news:opsnpibito23k2f5 nrage.netwin.co.nz...errorOn Tue, 15 Mar 2005 18:18:36 -0600, Charles <cee-lo green.com> wrote:Yea we've been trying to get Walter to make this a compile timeread.forever, he stands alone on the 'shut-up code' argument last IfurtherCan anyone give me a situation where no return is NOT an error, and therefore should not be caught at compile time ? I'd even goandsay 'not-all control paths return a value' should be a compile time error.The problem is not simply whether it's an error or not. It's whetherdocan correctly detect all cases, and the answer seems to be "no, you cannot", or, "you might be able to but it would take a lot of work toone,so". It's true that some C/C++ compilers attempt to, they also give false positives, meaning, when you get one you're not sure if it's a realor not. Regan"Andrew Fedoniouk" <news terrainformatica.com> wrote in message news:d17lpi$291e$1 digitaldaemon.com...Following program, being compiled in -debug, in runtime ends up with the following: C:\d\test>test.exe Error: AssertError Failure test(8) The source of the problem is in int something() - it does not have renturn value set. IMO, either this code must not compile at all or flag -w (warnings) should be 'on' by default. Andrew. ==test.d================ static int v = 0; int something(int vv) { v = vv; } int main(char[][] args) { something(28); } ==test.d==EOF=============
Mar 17 2005
Charles wrote:Yea we've been trying to get Walter to make this a compile time error forever, he stands alone on the 'shut-up code' argument last I read. Can anyone give me a situation where no return is NOT an error, and therefore should not be caught at compile time ? I'd even go further and say 'not-all control paths return a value' should be a compile time error.Well, as far as I am concerned, Walter does have a point, although it still could check whether there is any return statement at all (like in OP's case), and produce an error in the case there isn't. As for the example of where it's not an error: Something[] things; Something get(int id) { int pos=0; for (int a=0; a<things.length; a++) if (things[a].id==id) { return things[a]; } else if (things[a] is null) { return (things[a]=new Something(id)); } } Now, when the compiler sees this it will figure that the for loop can end, and there is no return after it. I, however, know that things[] is always long enough to contain a null and so the error will never happen. OTOH, if I put "return null" at the end just to silence the compiler, if there is actually a bug and things[] doesn't contain a null, I won't get the error here, where I should, but somewhere else, and it will also be the wrong error "someVar is null" instead of "things[] didn't contain a null".. xs0
Mar 16 2005
xs0 wrote:Charles wrote:I think the correct way to "shut the compiler up" in this case is to add an "assert(false);" statement to the end of the function. This lets the compiler know that execution must never reach that point, and, even better, it lets the people reading the code know that execution must never reach that point. All that's necessary is for DMD's flow analysis stuff to check for assert(false); -- andyYea we've been trying to get Walter to make this a compile time error forever, he stands alone on the 'shut-up code' argument last I read. Can anyone give me a situation where no return is NOT an error, and therefore should not be caught at compile time ? I'd even go further and say 'not-all control paths return a value' should be a compile time error.Well, as far as I am concerned, Walter does have a point, although it still could check whether there is any return statement at all (like in OP's case), and produce an error in the case there isn't. As for the example of where it's not an error: Something[] things; Something get(int id) { int pos=0; for (int a=0; a<things.length; a++) if (things[a].id==id) { return things[a]; } else if (things[a] is null) { return (things[a]=new Something(id)); } } Now, when the compiler sees this it will figure that the for loop can end, and there is no return after it. I, however, know that things[] is always long enough to contain a null and so the error will never happen. OTOH, if I put "return null" at the end just to silence the compiler, if there is actually a bug and things[] doesn't contain a null, I won't get the error here, where I should, but somewhere else, and it will also be the wrong error "someVar is null" instead of "things[] didn't contain a null"..
Mar 16 2005
"Andrew Fedoniouk" <news terrainformatica.com> wrote: [...]IMO, either this code must not compile at all or flag -w (warnings) should be 'on' by default.[...] Please describe an _algorithm_ that checks reliably for variables not initialized during runtime, because not having a `return' processed in a function during runtime is the same as leaving the implicit return value uninitialized. Otherwise just turn -w on for ever, if you want the compiler to nitpick on your code. -manfred
Mar 16 2005
Please describe an _algorithm_ that checks reliably for variables not initialized during runtime, because not having a `return' processed in a function during runtime is the same as leaving the implicit return value uninitialized.Theoretically such _algorithm_ does exist as each program is just a finite state automata, but practically full implementation is not feasible. D and Java deal with this by assigning implicitly null/0 to all variables (including return value). And this is good. My point is simple: if you can recognize "no return value" situation then this should not be a warning but just an error (which it is). I understand that for pre-0.117 versions there was only one way to deal with it - to place throw ErrorAssert at the end of function body block. But now this solution is obsolete I guess. Andrew. "Manfred Nowak" <svv1999 hotmail.com> wrote in message news:d1952k$s6n$1 digitaldaemon.com..."Andrew Fedoniouk" <news terrainformatica.com> wrote: [...]IMO, either this code must not compile at all or flag -w (warnings) should be 'on' by default.[...] Please describe an _algorithm_ that checks reliably for variables not initialized during runtime, because not having a `return' processed in a function during runtime is the same as leaving the implicit return value uninitialized. Otherwise just turn -w on for ever, if you want the compiler to nitpick on your code. -manfred
Mar 16 2005
"Andrew Fedoniouk" <news terrainformatica.com> wrote:Theoretically such _algorithm_ does exist as each program is just a finite state automata, but practically full implementation is not feasible.Agreed, but only because I did not express precisely, what I was talking of.D and Java deal with this by assigning implicitly null/0 to all variables (including return value). And this is good.But this assignment is done at compile time, while my request was on checking for runtime assignements. But I admit that this might be nitpicking on my words: I wanted to ask for an _algorithm_ that checks if every variable is used at runtime or initialized to some useful value at runtime, thereby considering the value of the automatic initialization as not useful under every circumstances. Do you admit that the existence of any such _algorithm_ implies a solution to the halting problem?My point is simple: if you can recognize "no return value" situation then this should not be a warning but just an error (which it is).[...] To issue the warning "no return value at the end of the function" the compiler has to check only the last statement of the function nothing else, and as it has been pointed out in this thread, the missing of such a `return' is not a sure indication for an error. And if you are content with automatic initializations you shouldn't demand a compile time error instead of a runtime error, but the automatic returning of a default value, if the end of the value returning function is reached. -manfred
Mar 16 2005
To issue the warning "no return value at the end of the function" the compiler has to check only the last statement of the function nothing else, and as it has been pointed out in this thread, the missing of such a `return' is not a sure indication for an error.As far as I can see Walter is already doing analysis of AST for exit points ( fallOffEnd() method ). Not sure though - just took a brief look. So detection of "not all control paths return a value" is already there. BTW: "not all control paths return a value" in C is a warning and in Java it is an error - will not compile at all. I cannot see any reasons to go C way here. Do you? Andrew. "Manfred Nowak" <svv1999 hotmail.com> wrote in message news:d1af1t$2ce7$1 digitaldaemon.com..."Andrew Fedoniouk" <news terrainformatica.com> wrote:Theoretically such _algorithm_ does exist as each program is just a finite state automata, but practically full implementation is not feasible.Agreed, but only because I did not express precisely, what I was talking of.D and Java deal with this by assigning implicitly null/0 to all variables (including return value). And this is good.But this assignment is done at compile time, while my request was on checking for runtime assignements. But I admit that this might be nitpicking on my words: I wanted to ask for an _algorithm_ that checks if every variable is used at runtime or initialized to some useful value at runtime, thereby considering the value of the automatic initialization as not useful under every circumstances. Do you admit that the existence of any such _algorithm_ implies a solution to the halting problem?My point is simple: if you can recognize "no return value" situation then this should not be a warning but just an error (which it is).[...] To issue the warning "no return value at the end of the function" the compiler has to check only the last statement of the function nothing else, and as it has been pointed out in this thread, the missing of such a `return' is not a sure indication for an error. And if you are content with automatic initializations you shouldn't demand a compile time error instead of a runtime error, but the automatic returning of a default value, if the end of the value returning function is reached. -manfred
Mar 16 2005
"Andrew Fedoniouk" <news terrainformatica.com> wrote: [...]BTW: "not all control paths return a value" in C is a warning and in Java it is an error - will not compile at all. I cannot see any reasons to go C way here. Do you?I see at least one reason: distribution of return statements over several control paths increases computational complexity. Reasonings: increase of computational complexity ---> severe sign for increased needs on human factors in understanding the code. ---> sign of reduced maintainability ---> increased costs ---> contradiction to a main goal of the design of D Although cost reduction is a main goal in the design of D this NG has not evolved any cost model. So I cannot prove in an accepted way the increase of costs by introducing automatic checking of all control paths for the existence of a `return'. Conclusion: Having more than one return in a function is bad style and the compiler should not support bad style. -manfred
Mar 17 2005
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Manfred Nowak schrieb am Thu, 17 Mar 2005 11:54:38 +0000 (UTC):"Andrew Fedoniouk" <news terrainformatica.com> wrote: [...]Are your working on memory restrained devices? It's the only place where the one-function-one-return style is usefull. Unless your are solving fairly trivial problems your functions will get some complexity and trying to use one return per function can drastically increase the complexity further(-> goto). Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFCOXQR3w+/yD4P9tIRAp1gAKC+7GREhS5N7mGTrAdhX1M4uMTdagCgpnlh f3rKp18jej4HeazWJusi6j0= =/vkK -----END PGP SIGNATURE-----BTW: "not all control paths return a value" in C is a warning and in Java it is an error - will not compile at all. I cannot see any reasons to go C way here. Do you?I see at least one reason: distribution of return statements over several control paths increases computational complexity. Reasonings: increase of computational complexity ---> severe sign for increased needs on human factors in understanding the code. ---> sign of reduced maintainability ---> increased costs ---> contradiction to a main goal of the design of D Although cost reduction is a main goal in the design of D this NG has not evolved any cost model. So I cannot prove in an accepted way the increase of costs by introducing automatic checking of all control paths for the existence of a `return'. Conclusion: Having more than one return in a function is bad style and the compiler should not support bad style.
Mar 17 2005
Thomas Kuehne <thomas-dloop kuehne.thisisspam.cn> wrote: [...]Are your working on memory restrained devices? It's the only place where the one-function-one-return style is usefull.Please explain your statement. I do not see any correlation between the facts in your first sentence and the statement in your second sentence. But if you want to state, that memory is cheap and that this cheapness should have consequences to programming and therefore language design you might be right. For example the richness of types in C might stem from the fact that memory was expensive in the times when C was designed. Do we really need byte, short, int and long? If memory is cheap only one type will do: long. If memory is cheap we can easily get rid of the uninitialized/unused variable problem at least at runtime: accompany every variable with a state register capable of containing the states DECLARED, INITIALIZED, USED and make sure that every assignment toggles the state from DECLARED to INITIALIZED, that every lookup throws an exception if the state shows DECLARED and otherwise the state is set to USED. Finally, when the function/program terminates make sure, that for every variable the state is USED. -manfred
Mar 18 2005
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Manfred Nowak schrieb am Fri, 18 Mar 2005 09:05:28 +0000 (UTC):Thomas Kuehne <thomas-dloop kuehne.thisisspam.cn> wrote: [...]Compare the unoptimized assembler outputs of a reasonable complex function with several potential return points using gotos or multiple returns. Depending on your very source code the one-return style usually saves you a few bytes in the executeable. If you don't have to count the bytes I'd recomend to use D's "nested" functions to clean up your code. ThomasAre your working on memory restrained devices? It's the only place where the one-function-one-return style is usefull.Please explain your statement. I do not see any correlation between the facts in your first sentence and the statement in your second sentence.For example the richness of types in C might stem from the fact that memory was expensive in the times when C was designed. Do we really need byte, short, int and long? If memory is cheap only one type will do: long.Memory isn't the only limited resource. Compare float+float, int+int, and long+long in a benchmark.If memory is cheap we can easily get rid of the uninitialized/unused variable problem at least at runtime: accompany every variable with a state register capable of containing the states DECLARED, INITIALIZED, USED and make sure that every assignment toggles the state from DECLARED to INITIALIZED, that every lookup throws an exception if the state shows DECLARED and otherwise the state is set to USED. Finally, when the function/program terminates make sure, that for every variable the state is USED.This would be a nice feature for debug builds. Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFCOqGK3w+/yD4P9tIRAj/SAJ9fQlJ8MaTXfGiGhvWAZkAitGTcJACggY86 UGVCkUgN/DtbAv/UjEa173c= =aTVg -----END PGP SIGNATURE-----
Mar 18 2005
Manfred Nowak wrote:Conclusion: Having more than one return in a function is bad style and the compiler should not support bad style.I'm not sure that eg. adding a flag variable or using goto is better ? (being the usual workarounds, for languages with just one return path) Having several return statements is a very common form to use.... See: http://www.refactoring.com/catalog/replaceNestedConditionalWithGuardClauses.html http://c2.com/cgi/wiki?GuardClause Just because it *could* be bad style, does not mean that it always is ? Sometimes using "return" or "break" is the clearest way of expression. But I haven't seen many people, except Walter, use gotos beyond 90's :-) --anders PS. Pre-condition contracts could be used to check *programmer* params. This was just one example of when multiple returns could be useful.
Mar 17 2005
Anders F Björklund <afb algonet.se> wrote: [...]I'm not sure that eg. adding a flag variable or using goto is better ? (being the usual workarounds, for languages with just one return path)You are right that my argument of increased computational complexity might be too short sighted, because my reasonings on increased computational complexity do not hold, when the increased computational complexity serves a task that must be done otherwise by the human factor. You are right that multiple `return's can be replaced by flag variables or gotos, thereby obfuscating the existence of multiple exit points. So the question arises whether multiple exit points are imposed on the code from the underlying problem, with the reasoning, that their existence is not a sign of bad style. And if they are imposed from the underlying problem how they are dealed with best.Having several return statements is a very common form to use.... See: http://www.refactoring.com/catalog/replaceNestedConditionalWithGu ardClauses.html http://c2.com/cgi/wiki?GuardClauseAs always it is not proved, that the use of this "refactoring" decreases the costs. I prefer another style than that suggested in the first example: <example> bit exceptions= _isDead || _isSeparated || _is Retired; if( ! exceptions ) result= normalPayAmount; else throw new exception( "not yet implemented"); return result; </example> as a first implementation and then filling out the cases for the exceptions.Just because it *could* be bad style, does not mean that it always is ? Sometimes using "return" or "break" is the clearest way of expression.Agreed, but how can you prove that multiple exit points are imposed on the code from the underlying problem?But I haven't seen many people, except Walter, use gotos beyond 90's :-)gotos are not always a sign of bad style. Forward gotos may have their right of existance. Otherwise you have to declare multiple returns as bad style, because, as you stated yourself, multiple returns are just replacements of forward gotos to the one and only return at the end of a function. -manfred
Mar 18 2005
Manfred Nowak wrote:Yes, you are right in that these refactorings usually swing both ways... For some code, it makes sense to convert from flags into single returns. And for other code, it is better to use flags and gotos - as suggested. This does not make either of them "bad" (in general) Just in some cases. So I still don't see how you say that "multiple returns are bad style" ? BTW; Refactoring is a good book to read, or at least brush up on the concept: http://martinfowler.com/books.html#refactoringHaving several return statements is a very common form to use.... See: http://www.refactoring.com/catalog/replaceNestedConditionalWithGu ardClauses.html http://c2.com/cgi/wiki?GuardClauseAs always it is not proved, that the use of this "refactoring" decreases the costs. I prefer another style than that suggested in the first example: <example> bit exceptions= _isDead || _isSeparated || _is Retired; if( ! exceptions ) result= normalPayAmount; else throw new exception( "not yet implemented"); return result; </example> as a first implementation and then filling out the cases for the exceptions.I didn't say that Walter's code is that bad... ( did I? :-) ) Just that some people can't stand the smell of "goto", and thus will have nothing to do with it - even if would help them a lot. Most compilers, and I believe also DMD, weighs the cost of: a) doing the return statement "inline" b) branching to an end return "block" Usually it depends on the return value, and the amount of cleanup. (including both exceptions, and tearing down stack frame and such) Fortunately, D - being a language for adults, let's *us* choose ? :-) Some times even TOO much... ("How would you like your strings, sir?" "UTF-8 or UTF-16?"; "What programming paradigm do you want today?" etc) --andersBut I haven't seen many people, except Walter, use gotos beyond 90's :-)gotos are not always a sign of bad style. Forward gotos may have their right of existance. Otherwise you have to declare multiple returns as bad style, because, as you stated yourself, multiple returns are just replacements of forward gotos to the one and only return at the end of a function.
Mar 18 2005