[Tutor] Re: Re: small program in Python and in C++

alan.gauld@bt.com alan.gauld@bt.com
Tue, 16 Jul 2002 18:11:54 +0100


Hi Dman,

> I thought only ASM needed a line of comment per line of code ;-).
> Whatever happened to self-documenting code?

It's alive and well, but most corporate coding standards 
require extensive comment block headers at the top of 
each file as well as above each function. Thus a 5 line 
function may have a 15 line header on top!(see our 
local example appended at the end...)

> | In the real world many functions contain 200 plus lines of 
> | executable code(*) which means maybe 400-500 lines of text.
> 
> I'm glad I'm not in the "real world" ;-).

Sorry, that sounded a bit patronising. A better term might 
have been "industrial scale" software projects. 
eg Air traffic Control, Nuclear reactors, Telephone exchanges 
and the like. (Recall we were talking about C++ projects 
in this thread not Python!)

> Yeah, I can see 100 lines of
>     stream << this->foo

More usually 100 times:

 if (this->foo) || (this->bar){
      stream << this->foo;
 }

ie 300 lines!

> attribute should have its own self-contained serialization function,

Could be but for primitive types that makes the files even 
bigger and most attributes will be either integers, floats 
or strings - ie the things you can store in an RDBMS.

> | time consuming and error prone. Jumping to the top of the function 
> | is a single keystroke!
> 
> Which keystroke, btw?  It would be helpful if I knew it.  

> I know how to use ctags, but that's quite a few keystrokes 
> (depending on function names and polymorphic ussage)

It shouldn't be if your ctags is C++ aware...
However ctags doesn't help for the current function, 
but [[ should go to the start of a paragraph in text 
mode or the start of the current function in C/C++ mode.

I just tried it and it relies on you putting your opening 
brace in the leftmost collumn (Which I do normally so it 
works for me  :-) like so:

void foo()
{
   //blah blah
   if(bar){
      //blah2
   }
   return;
}

> | Well written variable declarations should all be commented! :-)
> 
> It shouldn't need a comment, except in the *few* (right? ;-))
> not-so-obvious cases :-).

Not so obvious is rarely the case in my experience. What the 
original programmer thinks is obvious very rarely is to somebody 
else later! (Of course the fact that modern compilers tend to 
allow more than 6 characters in variables helps ;-)

> | Only if reading the code sequentially, if you are jumping in 
> | at random - as is usually the case for maintenance programmers 
> THat makes sense.

Just to elaborate. The normal mode of operation for a 
maintenance programmer with a hot fault is to load up 
the executable in the debugger with a core dump(if Unix or MVS)
and do a stacktrace. They will then navigate up the stack 
which means they arrive in the upper level function 
wherever the call to the lower level one was made, not 
at the entry point..

> | A crash in those circumstances is a good thing! And NULLS help 
> | achieve it!
> 
> While I agree here, what if you got a 'NameError' exception instead of
> 'AttributeError: None object has no member foo' _or_ if the operation

We were talking C++ remember. A Name error will be caught at 
compile time in C++.

> you performed was perfectly valid with None/NULL but that was not the
> value the variable should have had.

There are obviously a few possible cases where this can happen 
but to be honest they are very rare. If you think abouit it 
most functions that accept a NULL do so only to indicate 
that a default value be used instead

Pythonically:

def foo(a=None):
  if a == None: a = 42
  # continue using a now good a...

There are very few valid uses for NULL or 0 in C/C++.

> | I see the point of wasted resource but not sure how Java/Python 
> | helps here. If you initialize the variable to a dummy object you 
> Here's an example :
> 
> // C++
> class Foo
> {
> }
> 
> void func()
> {
>     Foo local_foo ;

Ah yes, non dynamic classes. I forgot about those in C++, 
I hardly ever use them. You are quite right, in those cases 
premature initialisation would waste resource.

> One way to avoid it is to use a pointer, and then allocate the object
> using 'new' when you need it.  Then you must remember to 'delete' it
> afterwards.  Also, supposedly, the heap is slower than the stack.

I always use dymanic objects in C++ and the performance 
overhead is minimal. The loss of polymorphism in statically 
declared classes is much more serious IMHO!

> (I also like python's ability to get rid of a local ('del') after
> you're done with it.  It helps prevent you from erroneously re-using
> the old data later on -- which I've done before!)

Yes memory management is a perennial problem in C/C++, it's about
the only good thing I have to say about Java :-)

> Surely if you can actually and accurately quantize the effect, then
> you can make a better argument than aesthetics.  

Unfortunately there is a wealth of objective collected data about
maintenance programming. Its always seem as a cost rather than 
revenue earner so the bean counters monitor it closely. Sadly 
the mainsatream software community seems to ignore it by and 
large! Possibly because it invariable originates in industry 
rather than  academia? No surely not... :-)

> benefits of each method and choose the best one.  Since quantization
> isn't a viable option, experience is the next best decider.  

I'm interested in why you think quantization is hard? 
Measuring time to fix, lines changed, code quality metrics 
etc is part and parcel of every maintenance teams work that 
I've ever worked with (erm, thats only 3, all in the same 
organisation BTW!!)

> My comments here aren't intended as arguments, just clarification of
> what I had said before and of the "other" perspective.  (and some of
> it is meant to be a bit humorous)

Me too, I must apologize if my earliuer post sounded a bit 
pompous, its an unfortunate tendency I have. They were meant 
entirely as my personal experience of maintaining large scale 
projects. (The first was 3,500,000 lines of C/C++, the second 
500,000 lines of C++ and the 3rd 350,000 lines of COBOL)

Hopefully there are some points of interest to the general 
Python community in here too, hidden amongst the rantings :-)

Alan G.
(Just returned from a week without computer access!)

Function header template:

###################################
# Signature:
#
# Input parameters:
# 
# Output Parameters:
#
# Operation:
#
# Notes:
#
# Maintenance History:
#
###################################

That has to be filled in for every function regardless 
of how small... A similar but bigger template is filled 
in at the top of every file includeiong the full RCS log...