Re: return in void functions
From: Jeff Schwab (jeffplus_at_comcast.net)
Date: 01/03/04
- Next message: Grimble Gromble: "Re: CLass members; public, private, protected and ???"
- Previous message: Andrew Koenig: "Re: return in void functions"
- In reply to: Martijn Lievaart: "Re: return in void functions"
- Next in thread: Martijn Lievaart: "Re: return in void functions"
- Reply: Martijn Lievaart: "Re: return in void functions"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Sat, 03 Jan 2004 11:42:15 -0500
Martijn Lievaart wrote:
> On Sat, 03 Jan 2004 10:23:14 -0500, Jeff Schwab wrote:
>
>
>>>You'll have a hard time tracing exceptions with this design. Why not
>>>define a trace object, that prints in constructor and destructor? Much
>>>easier to use and works with multiple returns and exceptions. It's what I
>>>do if I need this.
>>
>>So, each time you want to debug a function with multiple return points,
>>you must:
>>
>>1) Define a class with member references to all of the function's local
>>variables; at least, the ones you want to trace.
>
>
> No, use one trace class to trace the program flow. When I want to log
> variables, I use a different (though related) class.
>
>
>>2) Find a cozy place somewhere before any of the function's return
>>points, but after all the traced variables have been defined. IME, this
>>is often impossible. Here is a simplistic case that reflects the common
>>practice of defining some variable, returning if a check succeeds, and
>>otherwise defining some other variables:
>>
>>template< typename T >
>>void sort_two_objects( T a, T b )
>>{
>
> TRACE(sort_two_objects);
>
>
>> bool already_sorted = a < b;
>>
>> // A Trace object defined here cannot trace the value of
>> copy_of_a, // even if the return statement is not used.
>
>
> see below
>
>
>> if( already_sorted )
>> {
>> return;
>> }
>>
>> // A Trace object defined here will not be destructed if the
>> return // statement is used.
>>
>> T copy_of_a = a;
>
>
> LOG("copy_of_a=" << a);
>
>
>> a = b;
>> b = copy_of_a;
>>}
>
>
> Why do it any other way? Yes multiple exit points can make ad-hoc
> cerr-debugging harder, but one should not do that anyhow. Writing the
> TRACE and LOG macros is pretty trivial and make life much easier.
>
>
>>>I never was a fan of not allowing multiple exit points, but exceptions
>>>embedded it in the language, so I guess we better get used to it. I
>>>know I don't have any problem with it.
>>
>>Exceptions do provide "extra" exit points, but they are not the same as
>>return statements. Exceptions carry information back up the call stack
>>about what went wrong, and why. Often, the information obtained in a
>>high-level catch block is sufficient, and there is no need to look at
>>the lower-level code at all. Even when there is such a need, since my
>>exceptions always include the line number and file number of the
>>corresponding throw statement, I know exactly which exit point to watch.
>
>
> That is true, but I don't see what the problem with multiple exit points
> is if you're going to rerun the program under the debugger anyhow.
>
> The only real advantage I can see of avoiding multiple exitpoints is that
> one can put a breakpoint on the common exit. In practice, I don't miss it.
>
>
>>>Obviously, multiple exit points, like any language feature can be used
>>>and mis-used. I concur that they can introduce problems, but only if
>>>mis-used. My personal guideline in this is that the code should read
>>>like a story. If not, you have a maintenance problem at least. So this
>>>is not really related to multiple exit points, but to obfuscated
>>>coding.
>>
>>I've heard that theory before. The fact is that programs are not
>>stories. When I'm debugging a large piece of code, I have no desire to
>>start at the beginning and proceed to the point of the problem. The
>>time required for such an approcach is linear with the number of lines
>>leading to the point of the problem. By doing instead a binary search
>>for the problem, debug time is significantly reduced. This approach is
>>eased greatly by the absence of spurious return statements. Any extra
>>return statement is what I would call "obfuscated code."
>
>
> I'm not talking about complete programs being stories, I'm talking about
> pieces of code, most probably a function. If you do that, the complete
> program is easy to read and debugging gets much easier. So your argument
> about binary search is not relevant, that is how one should always debug.
>
> If the program is hard to read, it is hard to debug. If multiple exit
> points make a function harder to read, they are misused. I still don't see
> why multiple exit points would be a problem here.
>
> M4
>
I think we're just not going to agree on this one. I don't care for
your TRACE and LOG macro approach, and I can see that you hate the idea
of giving up the ability to exit a function wherever you see fit. I
congratulate you on having found techniques that work for you, but they
certainly are not appropriate for me. I still recommend avoiding
multiple return points wherever possible, with the exception of... well,
exceptions. :)
-Jeff
- Next message: Grimble Gromble: "Re: CLass members; public, private, protected and ???"
- Previous message: Andrew Koenig: "Re: return in void functions"
- In reply to: Martijn Lievaart: "Re: return in void functions"
- Next in thread: Martijn Lievaart: "Re: return in void functions"
- Reply: Martijn Lievaart: "Re: return in void functions"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|