This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Remove parameter names from libiberty.h


You wrote:

>Personally, I like parameter names as documentation, and I'd recommend
>moving the inclusion of libiberty.h higher in opcodes/m88k-dis.c so
>that "mode" isn't clobbered by the time we get these prototypes, but
>it's not worth arguing over IMO.

I'm siding with Alan there, but for the sake of it, I believe you
deserve an explanation for why it's the right thing to do, and not
just a matter of taste and style.

Simply-put: parameter names in prototypes will get you, sooner or
later.

C is an annoying language without enough namespaces, and where the
preprocessor can tramp all over the place.

>From time to time, it breaks function declarations. I've had my share
of 3rd party software that includes a bunch of system includes 
like sys/types.h, and then defines a swap32 function that just happens
to collide with the macro of the same name in my system includes.

This doesn't happen with standard function declarations, because, well,
they're standard, so people will tend to avoid that namespace, even for
preprocessing purposes... well, not always, and when gcc started warning
for log(), I first had to check my standard that, yes, indeed log is always
reserved, even if you don't include math.h, and that all the system 
administration utilities that just wanted to output information to a journal
were wrong to name that function log.

Enter parameter names. Same trouble, all over again, but worse. See, no
standard defines the names that parameters should have. There's no way
to enforce anything there, since C is strictly positional, and doesn't
care one bit if you write extern void f(int foo);  in one file and then
write the actual function
void
f(int bar)
{
}

Okay, enough background, that you definitely know already. So, parameter
names are not reserved, and no API tells you to avoid them, and so, sooner
or later, someone with a loaded preprocessor uses just the name you
carefully crafted for your prototype.  Basically, it's a collision between
two system-wide problems: header files that get included all over the place,
and a preprocessor that doesn't understand the language beyond lexing.

You can HAVE parameter names, but sooner or later, this will break
something somewhere, and generate A LOT of head scratching, especially
from beginners who haven't yet figured gcc -save-temps or gcc -dM.

And it translates to further headaches down the road when you have
parameter names, and you work on a BIG project, and so you have to work
around preprocessor collisions, and so you reorder your header files, up
to a point, when you finally figure out that it can't work, because you've
got header inter-dependencies going one way, and parameter names + macros
going the other way. So you start adding MORE include guards, as if the
forest of #ifdef wasn't bad enough already...

You will end up getting it to work, after having lost hours to it (generally,
header file breakage occurs just after you went to bed, having launched
a full compile that's supposed to take four hours)... only for it to be so
brittle that it breaks the next time someone changes anything.

Okay, for sure, there's a lot of preprocessor/header issues that have
nothing to do with parameter names. But parameter names is a heavy 
maintenance issue, doesn't lead to robust source code, and frankly, it
doesn't give you all that much in the area of documentation.

Put simply, it's not worth it, and real bad software engineering practice.
Put even more simply, there's a parameter name with your name on it,
and sooner or later, it will get you.

So, in OpenBSD, we killed them. We don't go out of our way to fix every
userland program includes, because `if it ain't broke, don't fix it', but
when we write new stuff, we don't put it in.

If you really want comments, well, add comments.
Some people like this style:
extern FILE *fopen_unlocked (const char * /* path */, const char * /* mode */);
personally I prefer:
/* file = fopen_unlocked(path, mode); */
extern FILE *fopen_unlocked (const char *, const char *);


Quick plug for a good book: Lakos `Large scale C++'. Really worth it.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]