February 25, 2002
"Russ Lewis" <spamhole-2001-07-16@deming-os.org> wrote in message news:3C7A6D64.853E54E8@deming-os.org...
> I guess I'm not understanding what you're getting at here.  Can you
explain
> or give example code?  It seems (at first glance) that it would be trivial
to
> see if all code paths return a value...

int foo(int i)
{
    if (i)
        return bar();
    else
        exit(0);
}

Putting in a dummy return after the exit(0) will satisfy the compiler demanding a return, but is a clarity/maintenance problem because the person reading the code will be misled by the existence of code that is never intended to be executed.


February 25, 2002
Walter wrote:

> Putting in a dummy return after the exit(0) will satisfy the compiler demanding a return, but is a clarity/maintenance problem because the person reading the code will be misled by the existence of code that is never intended to be executed.

Right, understood.  But then again, can exit() fail?  I don't think that exit()
can, but others (like exec()) can.  Personally, I prefer to force the explicit
(unused) return (provided that it is well commented).  However, I understand
that others have other opinions, and I think it's time I bow out.

--
The Villagers are Online! villagersonline.com

.[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ]
.[ (a version.of(English).(precise.more)) is(possible) ]
?[ you want.to(help(develop(it))) ]


February 25, 2002
Richard Krehbiel wrote:

> int missing_return(int code)
> {
>    switch(code)
>    {
>    case -1:
>       return 10;
>    case 0:
>       return 20;
>    case 1:
>       return 30;
>    }
> }

A compiler can easily detect a missing default case and issue the error.  In
fact, this is a good error checking mechanism:
    throw Exception("unexpected value passed to missing_return()");

Of course, it would be even better to use an in-condition stating the valid range of the variable!

> Now, the programmer has omitted a "default:" case because he is confident that this function will only be called with -1, 0, or 1 - and let's assume he's actually right this time.  :-)  But the compiler doesn't know; it thinks there's another possible code path, that falls out of the switch and finds a valued-return missing.

If there was an explicit in-case stating the range, then there *is* a return value for the "invalid" cases - it is to throw an exception from the in-block. Thus, a D compiler doesn't face this problem (though a C compiler does).

> Now, if the programmer's debugging, there might be a faulty call to this function.  So inserting code to throw an exception if the end of the function is reached would be better than simply returning an unknown value.
>
> You get the same effect by just inserting a debug-conditional statement that throws.  But it might be nice if the compiler did it, so the programmer doesn't have to remember it all the time.

Makes sense.

--
The Villagers are Online! villagersonline.com

.[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ]
.[ (a version.of(English).(precise.more)) is(possible) ]
?[ you want.to(help(develop(it))) ]


February 25, 2002
"Russ Lewis" <spamhole-2001-07-16@deming-os.org> wrote in message news:3C7A6D64.853E54E8@deming-os.org...

> I guess I'm not understanding what you're getting at here.  Can you
explain
> or give example code?  It seems (at first glance) that it would be trivial
to
> see if all code paths return a value...

    int foo()
    {
        if (something)
            return 1;
        else
            return 2;
    }

    int bar()
    {
        int n = foo();
        if (n == 1)
            return 3;
        else if (n == 2)
            return 4;
    }

As you can see, we know that foo() can only return 1 or 2 - so our version of bar is safe. However, the compiler might have a problem checking this.




February 25, 2002
Pavel Minayev wrote:

>     int foo()
>     {
>         if (something)
>             return 1;
>         else
>             return 2;
>     }
>
>     int bar()
>     {
>         int n = foo();
>         if (n == 1)
>             return 3;
>         else if (n == 2)
>             return 4;
>     }
>
> As you can see, we know that foo() can only return 1 or 2 - so our version of bar is safe. However, the compiler might have a problem checking this.

Specify an out-condition then?

--
The Villagers are Online! villagersonline.com

.[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ]
.[ (a version.of(English).(precise.more)) is(possible) ]
?[ you want.to(help(develop(it))) ]


February 25, 2002
Russ Lewis wrote:

> Specify an out-condition then?

d'oh!  I just said I'd bow out...well, at the very least, I won't offer any more opinions, if that's possible :)

--
The Villagers are Online! villagersonline.com

.[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ]
.[ (a version.of(English).(precise.more)) is(possible) ]
?[ you want.to(help(develop(it))) ]


February 25, 2002
"Walter" <walter@digitalmars.com> wrote in message news:a5drkm$1nbf$2@digitaldaemon.com...
>
> "Russ Lewis" <spamhole-2001-07-16@deming-os.org> wrote in message news:3C7A6D64.853E54E8@deming-os.org...
> > I guess I'm not understanding what you're getting at here.  Can you
> explain
> > or give example code?  It seems (at first glance) that it would be
trivial
> to
> > see if all code paths return a value...
>
> int foo(int i)
> {
>     if (i)
>         return bar();
>     else
>         exit(0);
> }
>
> Putting in a dummy return after the exit(0) will satisfy the compiler demanding a return, but is a clarity/maintenance problem because the
person
> reading the code will be misled by the existence of code that is never intended to be executed.

One can argue that the function should be rewritten as so:

int foo(int i)
{
    if (i)
        return bar();
    exit(0);
}

One could also argue that exit(0) is dangerous and should be avoided; use
throw instead.

If we could flag functions with some attribute (like "never returns") the compiler would be able to understand what's going on above.

Sean


February 25, 2002
"Russ Lewis" <spamhole-2001-07-16@deming-os.org> wrote in message news:3C7A79B2.6BAF3DEF@deming-os.org...

> > As you can see, we know that foo() can only return 1 or 2 - so our
version
> > of bar is safe. However, the compiler might have a problem checking
this.
>
> Specify an out-condition then?

Out-condition is not necessary a constant expression. In fact, there might be a rather complex block checking validity of return value... But in our case it could be as simple as:

    out (result)
    {
        assert(result == a || result == b);  // where a turns up being 1,
and b is 2
    }


February 26, 2002
"Sean L. Palmer" <spalmer@iname.com> wrote in message news:a5e1la$1q7p$1@digitaldaemon.com...
> If we could flag functions with some attribute (like "never returns") the compiler would be able to understand what's going on above.

True, but I like Pavel's idea of having the compiler insert a hidden throw there. To me, it solves the problem rather neatly!


February 26, 2002
"Russ Lewis" <spamhole-2001-07-16@deming-os.org> wrote in message news:3C7A79B2.6BAF3DEF@deming-os.org...
> Specify an out-condition then?

Won't be reliable because the return value will be garbage that might randomly look like valid data.


1 2
Next ›   Last »