digitalmars.D.learn - void main returning int - why compiles?
- Daren Scot Wilson (20/20) Dec 31 2010 I'm wondering why the following compiles. I'm using LDC. Perhaps it's ...
- Jonathan M Davis (5/33) Jan 01 2011 I don't know what LDC's current state is in terms of being up-to-date wi...
- Matthias Pleh (2/35) Jan 01 2011 It's the same with dmd v2.051 on GNU/Linux
- bearophile (11/12) Jan 01 2011 It's yet another small compiler bug, fit for Bugzilla.
- bearophile (8/16) Jan 01 2011 Simpler:
- Simen kjaeraas (18/22) Jan 01 2011 This is by design, the feature is made for generic functions. Consider:
- David Nadlinger (6/10) Jan 01 2011 I am not sure if this simple argument is valid – if Fn was of return
- bearophile (11/22) Jan 01 2011 I think you are talking about the foo() case. But the OP is talking abou...
- bearophile (1/1) Jan 01 2011 http://d.puremagic.com/issues/show_bug.cgi?id=5399
- Manfred_Nowak (9/11) Jan 01 2011 From the docs:
- bearophile (6/7) Jan 01 2011 You are right, thank you for the quotation. So I have updated this, beca...
- bearophile (18/26) Jan 02 2011 Walter has closer my issue with this comment:
I'm wondering why the following compiles. I'm using LDC. Perhaps it's a bug, or there's some subtlety about D. I have deliberately, out of a combination of idleness and desire for mischief, have main() declared as returning void, but with a return statement giving an integer. If the first "half evil" return statement is uncommented, the corruption is noticed by the compiler and it writes an error. As shown, the "total evil" return statement gets a value from subroutine foo(). Being somehow so perfect in its evilness, this passes through the compiler without a burp. The resulting executable returns zero (or my bash shell defaults to zero when receiving nothing.) When I get religion and like good boy declare main() as returing int, it compiles in perfectly. When executed, the program returns either number according to which return statement is uncommented. int foo(int x) { return x; } void main() { // return 333; /* half evil */ return foo(666); /* total evil */ }
Dec 31 2010
On Friday 31 December 2010 23:37:17 Daren Scot Wilson wrote:I'm wondering why the following compiles. I'm using LDC. Perhaps it's a bug, or there's some subtlety about D. I have deliberately, out of a combination of idleness and desire for mischief, have main() declared as returning void, but with a return statement giving an integer. If the first "half evil" return statement is uncommented, the corruption is noticed by the compiler and it writes an error. As shown, the "total evil" return statement gets a value from subroutine foo(). Being somehow so perfect in its evilness, this passes through the compiler without a burp. The resulting executable returns zero (or my bash shell defaults to zero when receiving nothing.) When I get religion and like good boy declare main() as returing int, it compiles in perfectly. When executed, the program returns either number according to which return statement is uncommented. int foo(int x) { return x; } void main() { // return 333; /* half evil */ return foo(666); /* total evil */ }I don't know what LDC's current state is in terms of being up-to-date with the latest D. However, it is _not_ legal D to return a value from a void function. So, this is definitely a bug in LDC. - Jonathan M Davis
Jan 01 2011
On 2011-01-01 09:32, Jonathan M Davis wrote:On Friday 31 December 2010 23:37:17 Daren Scot Wilson wrote:It's the same with dmd v2.051 on GNU/LinuxI'm wondering why the following compiles. I'm using LDC. Perhaps it's a bug, or there's some subtlety about D. I have deliberately, out of a combination of idleness and desire for mischief, have main() declared as returning void, but with a return statement giving an integer. If the first "half evil" return statement is uncommented, the corruption is noticed by the compiler and it writes an error. As shown, the "total evil" return statement gets a value from subroutine foo(). Being somehow so perfect in its evilness, this passes through the compiler without a burp. The resulting executable returns zero (or my bash shell defaults to zero when receiving nothing.) When I get religion and like good boy declare main() as returing int, it compiles in perfectly. When executed, the program returns either number according to which return statement is uncommented. int foo(int x) { return x; } void main() { // return 333; /* half evil */ return foo(666); /* total evil */ }I don't know what LDC's current state is in terms of being up-to-date with the latest D. However, it is _not_ legal D to return a value from a void function. So, this is definitely a bug in LDC. - Jonathan M Davis
Jan 01 2011
Daren Scot Wilson:I'm wondering why the following compiles.It's yet another small compiler bug, fit for Bugzilla. If you want I may add a bug report to Bugzilla that shows this as "accepts-invalid": int foo(int x) { return x; } void main() { return foo(1); } Bye, bearophile
Jan 01 2011
If you want I may add a bug report to Bugzilla that shows this as "accepts-invalid": int foo(int x) { return x; } void main() { return foo(1); }Simpler: int foo() { return 1; } void main() { return foo(); } But maybe this bug report is already present. Bye, bearophile
Jan 01 2011
Daren Scot Wilson <darenw darenscotwilson.com> wrote:As shown, the "total evil" return statement gets a value from subroutine foo(). Being somehow so perfect in its evilness, this passes through the compiler without a burp. The resulting executable returns zero (or my bash shell defaults to zero when receiving nothing.)This is by design, the feature is made for generic functions. Consider: ReturnType!Fn wrap( alias Fn )( ParameterTypeTuple!Fn args ) { return Fn( args ); } One would expect that to work. If void functions did not allow returning the results of functions, the above function would have had to be changed to something like this: ReturnType!Fn wrap( alias Fn )( ParameterTypeTuple!Fn args ) { static if ( is( typeof( return ) == void ) ) { Fn( args ); } else { return Fn( args ); } } Clearly this code is worse than the above. -- Simen
Jan 01 2011
On 1/1/11 10:08 PM, Simen kjaeraas wrote:This is by design, the feature is made for generic functions. Consider: ReturnType!Fn wrap( alias Fn )( ParameterTypeTuple!Fn args ) { return Fn( args ); }I am not sure if this simple argument is valid – if Fn was of return type void, you would, type-wise, have »return void;« in a function returning void, which is clearly different from having »return someInt;« in a function returning void… David
Jan 01 2011
Simen kjaeraas:One would expect that to work. If void functions did not allow returning the results of functions, the above function would have had to be changed to something like this: ReturnType!Fn wrap( alias Fn )( ParameterTypeTuple!Fn args ) { static if ( is( typeof( return ) == void ) ) { Fn( args ); } else { return Fn( args ); } }I think you are talking about the foo() case. But the OP is talking about the bar() case, that I think it's a compiler bug: void foo() {} int bar() { return 1; } void main() { //return 0; // error //return foo(); // OK, foo returns void return bar(); // error, bar returns int } Bye, bearophile
Jan 01 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5399
Jan 01 2011
Daren Scot Wilson wrote:As shown, the "total evil" return statement gets a value from subroutine foo().From the docs: | Expression is allowed even if the function specifies a void return | type. The Expression will be evaluated, but nothing will be returned. | If the Expression has no side effects, and the return type is void, | then it is illegal. http://www.digitalmars.com/d/2.0/statement.html (cited 01/01/11) _and_ foo() is not marked to have no side effects. -manfred
Jan 01 2011
Manfred Nowak:_and_ foo() is not marked to have no side effects.You are right, thank you for the quotation. So I have updated this, because it's not a bug: http://d.puremagic.com/issues/show_bug.cgi?id=5399 I'm sure there's a rationale behind that special case in the D specs. Is someone able to explain? It looks like an unsafe corner case. Bye, bearophile
Jan 01 2011
Manfred Nowak:| Expression is allowed even if the function specifies a void return | type. The Expression will be evaluated, but nothing will be returned. | If the Expression has no side effects, and the return type is void, | then it is illegal. http://www.digitalmars.com/d/2.0/statement.html (cited 01/01/11) _and_ foo() is not marked to have no side effects.Walter has closer my issue with this comment: http://d.puremagic.com/issues/show_bug.cgi?id=5399It is not a dangerous corner case, it is a deliberate design choice. It is meant to facilitate writing generic code so that the same code can be generated for void and non-void return values.<But I don't understand still, I don't buy Walter's explanation still. I write my comments in D.learn because I don't want to fill Bugzilla with too much discussions. This compiles: int bar() { return 0; } void main() { return bar(); } While this doesn't, and this semantic difference looks like corner case of the general D rule (the good D rule seems that if it's a void function you can't return a value different from void, and if it's not a void function then you must return a value of the right type): int bar() { return 0; } void main() { auto temp = bar(); return temp; } If I want to create a void function foo(), and I want to generate code inside it, can't I just avoid to add a "return" statement in the generated code, instead of adding return and then letting the compiler silently ignore an eventually present return value? Bye, bearophile
Jan 02 2011