www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - return in void functions

reply bearophile <bearophileHUGS lycos.com> writes:
D has safeties to avoid this kind of code, because it's essentially considered
a bug:

int foo() {}
void main() {
    foo();
}


But this compiles with no errors:

void foo() {
    return 1;
}
void main() {
    foo();
}


Notice that this Java code:

class Test {
	static void foo() {
		return 1;
	}

    public static void main(String[] args) {
		Test.foo();
    }
}

Raises a compilation error:

Test.java:3: cannot return a value from method whose result type is void
                return 1;
                       ^
1 error

I think this avoids some mistakes.

Bye,
bearophile
Mar 04 2009
next sibling parent reply BCS <ao pathlink.com> writes:
Reply to bearophile,


 But this compiles with no errors:
 
 void foo() {
 return 1;
 }
 void main() {
 foo();
 }
IIRC D allows "return exp;" in a void function because it avoids special cases in template code. ReturnTypeOf!(AFn, T) fn(T)(T t) { return AFn(t,t); // AFn might return void }
Mar 04 2009
next sibling parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
BCS wrote:
 Reply to bearophile,
 
 
 But this compiles with no errors:

 void foo() {
 return 1;
 }
 void main() {
 foo();
 }
IIRC D allows "return exp;" in a void function because it avoids special cases in template code. ReturnTypeOf!(AFn, T) fn(T)(T t) { return AFn(t,t); // AFn might return void }
Sadly, this doesn't help if you need to cache the result before exiting. I personally wish we could create void *variables*. -- Daniel
Mar 04 2009
parent reply grauzone <none example.net> writes:
Daniel Keep wrote:
 
 BCS wrote:
 Reply to bearophile,


 But this compiles with no errors:

 void foo() {
 return 1;
 }
 void main() {
 foo();
 }
IIRC D allows "return exp;" in a void function because it avoids special cases in template code. ReturnTypeOf!(AFn, T) fn(T)(T t) { return AFn(t,t); // AFn might return void }
Sadly, this doesn't help if you need to cache the result before exiting. I personally wish we could create void *variables*.
I wonder if we'd lose anything if the void datatype was completely removed and replaced by a "struct void {}" declaration in object.d?
   -- Daniel
Mar 04 2009
next sibling parent Daniel Keep <daniel.keep.lists gmail.com> writes:
grauzone wrote:
 Daniel Keep wrote:
 BCS wrote:
 Reply to bearophile,


 But this compiles with no errors:

 void foo() {
 return 1;
 }
 void main() {
 foo();
 }
IIRC D allows "return exp;" in a void function because it avoids special cases in template code. ReturnTypeOf!(AFn, T) fn(T)(T t) { return AFn(t,t); // AFn might return void }
Sadly, this doesn't help if you need to cache the result before exiting. I personally wish we could create void *variables*.
I wonder if we'd lose anything if the void datatype was completely removed and replaced by a "struct void {}" declaration in object.d?
   -- Daniel
T x = void; Interesting idea, though. -- Daniel
Mar 05 2009
prev sibling parent Max Samukha <samukha voliacable.com.removethis> writes:
On Thu, 05 Mar 2009 08:40:34 +0100, grauzone <none example.net> wrote:

Daniel Keep wrote:
 
 BCS wrote:
 Reply to bearophile,


 But this compiles with no errors:

 void foo() {
 return 1;
 }
 void main() {
 foo();
 }
IIRC D allows "return exp;" in a void function because it avoids special cases in template code. ReturnTypeOf!(AFn, T) fn(T)(T t) { return AFn(t,t); // AFn might return void }
Sadly, this doesn't help if you need to cache the result before exiting. I personally wish we could create void *variables*.
I wonder if we'd lose anything if the void datatype was completely removed and replaced by a "struct void {}" declaration in object.d?
That would be awesome. Would foo() and foo(void) be distinct overloads, one taking no arguments and the other taking a void argument? Should voids be allowed to be declared directly or only passed to template parameters?
   -- Daniel
Mar 05 2009
prev sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
BCS wrote:
 IIRC D allows "return exp;" in a void function because it avoids special 
 cases in template code.
 
 ReturnTypeOf!(AFn, T) fn(T)(T t)
 {
    return AFn(t,t); // AFn might return void
 }
Yes, that's exactly why.
Mar 04 2009
next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Walter Bright" <newshound1 digitalmars.com> wrote in message 
news:gomvoo$1m3b$3 digitalmars.com...
 BCS wrote:
 IIRC D allows "return exp;" in a void function because it avoids special 
 cases in template code.

 ReturnTypeOf!(AFn, T) fn(T)(T t)
 {
    return AFn(t,t); // AFn might return void
 }
Yes, that's exactly why.
There has to be a better way to handle that. Making "void foo(){return 1;}" valid code with no warning is just plain sloppy. (In fact, I've been bitten by that before.)
Mar 04 2009
next sibling parent BCS <none anon.com> writes:
Hello Nick,


 There has to be a better way to handle that.  Making "void
 foo(){return 1;}" valid code with no warning is just plain sloppy. (In
 fact, I've been bitten by that before.)
 
I wouldn't mind seeing it limited to "return FnReturningVoid();"
Mar 04 2009
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Nick Sabalausky wrote:
 "Walter Bright" <newshound1 digitalmars.com> wrote in message 
 news:gomvoo$1m3b$3 digitalmars.com...
 BCS wrote:
 IIRC D allows "return exp;" in a void function because it avoids special 
 cases in template code.

 ReturnTypeOf!(AFn, T) fn(T)(T t)
 {
    return AFn(t,t); // AFn might return void
 }
Yes, that's exactly why.
There has to be a better way to handle that. Making "void foo(){return 1;}" valid code with no warning is just plain sloppy. (In fact, I've been bitten by that before.)
I agree. It's fine to forward a void to a void, but not anything else to a void. Andrei
Mar 04 2009
prev sibling next sibling parent Yigal Chripun <yigal100 gmail.com> writes:
Walter Bright wrote:
 BCS wrote:
 IIRC D allows "return exp;" in a void function because it avoids
 special cases in template code.

 ReturnTypeOf!(AFn, T) fn(T)(T t)
 {
 return AFn(t,t); // AFn might return void
 }
Yes, that's exactly why.
D is becoming more functional and the functional way is to use a unit type. why not turn D's void from C style keyword to a unit type?
Mar 04 2009
prev sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Walter Bright wrote:
 BCS wrote:
 IIRC D allows "return exp;" in a void function because it avoids 
 special cases in template code.

 ReturnTypeOf!(AFn, T) fn(T)(T t)
 {
    return AFn(t,t); // AFn might return void
 }
Yes, that's exactly why.
Why it allows you to return an int from a void-returning function??? Stewart.
Mar 07 2009
parent Georg Wrede <georg.wrede iki.fi> writes:
Stewart Gordon wrote:
 Walter Bright wrote:
 BCS wrote:
 IIRC D allows "return exp;" in a void function because it avoids 
 special cases in template code.

 ReturnTypeOf!(AFn, T) fn(T)(T t)
 {
    return AFn(t,t); // AFn might return void
 }
Yes, that's exactly why.
Why it allows you to return an int from a void-returning function???
C does that, too. void foo() { return 23; } int main() { foo(); } Running the program gives random values as the exit status. Changing void to int returns always 23. (Actually I would have thought that it'd give 23 in both cases. But I guess the assignment of 23 into the return register doesn't get compiled when void is used.) ---- Anyway, I don't think this is such a big deal. Fixing this may be a lot of work, and I haven't heard anyone complain about it, in C or D, before. It's a blemish, but one we can live with.
Mar 08 2009
prev sibling next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Nick Sabalausky:
 There has to be a better way to handle that.
Possible idea: allowing functions too (and not just function templates as in D2) to have an "auto" return type?
(In fact, I've been bitten by that before.)<
Me too, that's why I have started this thread. Bye, bearophile
Mar 05 2009
parent reply Georg Wrede <georg.wrede iki.fi> writes:
bearophile wrote:
 Nick Sabalausky:
 There has to be a better way to handle that.
Possible idea: allowing functions too (and not just function templates as in D2) to have an "auto" return type?
void main() { auto a = f(); // Here, store a in a struct, i.e. you need to know the type // so that you can have the right kind of struct for it. } auto f() { auto c = g(); return c; } auto g() { auto c = h(); return c; } Then in a library (probably not even documented with the actual return type -- an understandable omission by this time...) auto h() { auto c = i(); return c; } auto i() { auto c = j(); // where j() is a non-public function. return c; } ...etc. So, isn't it easier for the programmer to know what the data type is, without going for goose chases every time?
Mar 06 2009
parent reply "Nick Sabalausky" <a a.a> writes:
"Georg Wrede" <georg.wrede iki.fi> wrote in message 
news:goqlhm$bg5$1 digitalmars.com...
 bearophile wrote:
 Nick Sabalausky:
 There has to be a better way to handle that.
Possible idea: allowing functions too (and not just function templates as in D2) to have an "auto" return type?
void main() { auto a = f(); // Here, store a in a struct, i.e. you need to know the type // so that you can have the right kind of struct for it. } auto f() { auto c = g(); return c; } auto g() { auto c = h(); return c; } Then in a library (probably not even documented with the actual return type -- an understandable omission by this time...) auto h() { auto c = i(); return c; } auto i() { auto c = j(); // where j() is a non-public function. return c; } ...etc. So, isn't it easier for the programmer to know what the data type is, without going for goose chases every time?
You could probably just do: auto a = f(); Stdout.formatln("{}", typeof(a).stringof); // Debug But I still wouldn't want to have to do that. Of course, that could arguably be solved by having automatic documentation automatically resolve the "auto". Although that would require 3rd party doc generators to do much more involved parsing.
Mar 06 2009
parent bearophile <bearophileHUGS lycos.com> writes:
Nick Sabalausky:
 Of course, that could arguably be solved by having automatic documentation 
 automatically resolve the "auto".
This seems a ncie idea for ddoc. Bye, bearophile
Mar 06 2009
prev sibling next sibling parent Georg Wrede <georg.wrede iki.fi> writes:
bearophile wrote:
 D has safeties to avoid this kind of code, because it's essentially considered
a bug:
 
 int foo() {}
 void main() {
     foo();
 }
 
 
 But this compiles with no errors:
 
 void foo() {
     return 1;
 }
 void main() {
     foo();
 }
No error in C either, only a warning. This being an easy thing to fix, one would think it'd been fixed ages ago already. Therefore, one only assumes there to be a motivation for having it like this.
Mar 06 2009
prev sibling parent Christopher Wright <dhasenan gmail.com> writes:
bearophile wrote:
 D has safeties to avoid this kind of code, because it's essentially considered
a bug:
 
 But this compiles with no errors:
 
 void foo() {
     return 1;
 }
 void main() {
     foo();
 }
This is an error you'll catch very quickly. If you never use the function, you won't have an error, which is a problem if you're releasing a library that you did not test.
Mar 06 2009