This was done on purpose, because in many cases one has received an
"object*" (e.g. as an argument), detects that it is a list by using
"is_listobject()", and then wants to access it as a list. If all the
list-specific functions took a "listobject*" as argument, one would
either have to copy the object into a local variable of that type, or
use a cast on each call. I am not very fond of casts (since the
compiler will happily cast e.g. a "char*" to "listobject*") so I
prefer to minimize their number.
It's true that now there's a cast inside listgetsize(), but that's one
cast per function definition instead of one cast per function call.
Also note that getlistsize() tests its argument for list-ness.
Strictly spoken this should be redundant, but many people (including
me!) sometimes write sloppy code that doesn't always check the types
of objects passing through a function. The function err_badcall()
(used in such occasions) currently raises an exception, but can easily
be changed to call abort(), which pin-points the cause of the error
much better than a segmentation violation caused by accessing a
non-list as if it were a list...
Finally note that at least it's reasonably consistent: newlistobject()
returns an "object*", and getlistsize() takes one...
> Can this be added to the "Clean Up List"???
Even if I did agree that it was a "good thing", cleaning this up would
be a major, boring coding effort, because (unlike identifier changes)
it can't be automated (or the automation would be as least as much
work).
--Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl>