From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 9496 invoked by alias); 14 Apr 2005 10:20:34 -0000 Mailing-List: contact binutils-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sources.redhat.com Received: (qmail 9102 invoked from network); 14 Apr 2005 10:19:45 -0000 Received: from unknown (HELO kraid.nerim.net) (62.4.16.104) by sourceware.org with SMTP; 14 Apr 2005 10:19:45 -0000 Received: from tetto.gentiane.org (espie.gentiane.org [62.212.102.210]) by kraid.nerim.net (Postfix) with ESMTP id 31AF142A20; Thu, 14 Apr 2005 12:19:44 +0200 (CEST) Received: from tetto.home (espie@localhost.my.domain [127.0.0.1]) by tetto.gentiane.org (8.13.1/8.12.11) with ESMTP id j3EAJhk2006014; Thu, 14 Apr 2005 12:19:43 +0200 (CEST) Received: (from espie@localhost) by tetto.home (8.13.1/8.12.11/Submit) id j3EAJe1t014378; Thu, 14 Apr 2005 12:19:41 +0200 (CEST) Date: Thu, 14 Apr 2005 10:20:00 -0000 From: Marc Espie To: binutils@sources.redhat.com Cc: ghazi@caip.rutgers.edu Subject: Re: Remove parameter names from libiberty.h Message-ID: <20050414101938.GA28001@tetto.home> Reply-To: espie@nerim.net Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.6i X-SW-Source: 2005-04/txt/msg00365.txt.bz2 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.