typedefs and structs

linas linas at austin.ibm.com
Wed Nov 9 11:30:48 EST 2005


On Tue, Nov 08, 2005 at 06:57:11PM -0500, Kyle Moffett was heard to remark:
> On Nov 8, 2005, at 18:23:27, linas wrote:
> >Off-topic: There's actually a neat little trick in C++ that can  
> >help avoid accidentally passing null pointers.  One can declare  
> >function declarations as:
> >
> >  int func (sturct blah &v) {
> >    v.a ++;
> >    return v.b;
> >  }
> >
> >The ampersand says "pass argument by reference (so as to get arg  
> >passing efficiency) but force coder to write code as if they were  
> >passing by value" As a result, it gets difficult to pass null  
> >pointers (for reasons similar to the difficulty of passing null  
> >pointers in Java (and yes, I loathe Java, sorry to subject you to  
> >that))  Anyway, that's a C++ trick  only; I wish it was in C so I  
> >could experiment more and find out if I like it or hate it.
> 
> That technique tends to cause more problems than it solves.  If I  
> write the following code:
> 
> struct foo the_leftmost_foo = get_leftmost_foo();
> do_some_stuff(the_leftmost_foo);
> 
> How do I know what it is going to do?  

It depends on how do_some_stuff() was declared. If its declared as

   do_some_stuff (struct foo &x)

then it will be a pass by reference.

> A much better solution is this:
> 
> void do_some_stuff(struct foo *the_foo) __attribute__((__nonnull__(1)));

Think of it as "syntactic sugar": the compiler "does the right thing"
without all the grungy extra markup such as __atribute. 

(Remember that at the dawn of time, C++ was just a bunch of pre-processor
markup that did nothing but hide grunge like __attribute__((whatever))
from the programmer. Only later did it become a language. Doing markup
like what you're suggesting is only a tiny step away from inventing a new
language, esp if you come up with some clever, unobtrusive markup for
it.)

> That ensures that the first argument cannot be explicitly passed as  
> null, 

Well, this misses the point. No one intentionally passes null pointers.
Its just that "shit happens". Pass-by-reference changes your coding
style. You tend to alloc on stack instead of malloc.  And then, since
its on stack, you know it would be very wrong to keep a pointer to it, 
and so you don't, you design code differently.  Usually, you discover 
you never really needed to hold a pointer to it anyway; you just did so
out of some ingrained habit.

And since its on stack, you can't leak memory, you don't need to 
reference count it. Much fewer mallocs & frees, so less likely to have
errors there. Better performance, and less memory fragmentation, for
what that's worth.

I dunno, I did this once on a larger, year-long project, and rather
liked it (I otherwise don't much like C++, since people tend to use
it in bad, horrible ways). I won't say this is the greatest 
coding style in the world, but it does change the way you think about 
designing code, mostly for the better.

--linas




More information about the Linuxppc64-dev mailing list