March 18, 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:
>> >> 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 ?
>>
>> Yes.
>>
>> > 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:
>> >> > 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=============
>> >> >>
>> >> >>
>> >> >
>> >> >
>> >>
>> >
>> >
>>
>
>

March 18, 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?GuardClause

As 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
March 18, 2005
Manfred Nowak wrote:

>>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?GuardClause
> 
> As 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.

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#refactoring


>>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.

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)

--anders
March 18, 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
March 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:
>
> [...]
>> 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.

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.

Thomas

> 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-----
1 2 3
Next ›   Last »