Jump to page: 1 2
Thread overview
void main returning int - why compiles?
Jan 01, 2011
Daren Scot Wilson
Jan 01, 2011
Jonathan M Davis
Jan 01, 2011
Matthias Pleh
Jan 01, 2011
bearophile
Jan 01, 2011
bearophile
Jan 01, 2011
Simen kjaeraas
Jan 01, 2011
David Nadlinger
Jan 01, 2011
bearophile
Jan 01, 2011
bearophile
Jan 02, 2011
Manfred_Nowak
Jan 02, 2011
bearophile
Jan 02, 2011
bearophile
January 01, 2011
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 */
}

January 01, 2011
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
January 01, 2011
On 2011-01-01 09:32, Jonathan M Davis wrote:
> 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


It's the same with dmd v2.051 on GNU/Linux
January 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
January 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
January 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
January 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
January 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
January 01, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5399
January 02, 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
« First   ‹ Prev
1 2