Date: Fri, 13 Jan 2012 00:47:37 +1100 (EST) From: Bruce Evans <brde@optusnet.com.au> To: Kostik Belousov <kostikbel@gmail.com> Cc: svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org, Guy Helmer <ghelmer@freebsd.org> Subject: Re: svn commit: r229986 - head/lib/libutil Message-ID: <20120112235635.Y1663@besplex.bde.org> In-Reply-To: <20120112001630.GS31224@deviant.kiev.zoral.com.ua> References: <201201112233.q0BMXfgD079582@svn.freebsd.org> <20120112001630.GS31224@deviant.kiev.zoral.com.ua>
next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, 12 Jan 2012, Kostik Belousov wrote: > On Wed, Jan 11, 2012 at 10:33:41PM +0000, Guy Helmer wrote: >> Log: >> Fix namespace issues with prototype parameter names. >> Add missing prototype parameter names. >> >> Requested by bde. >> ... >> Modified: head/lib/libutil/libutil.h >> ============================================================================== >> --- head/lib/libutil/libutil.h Wed Jan 11 22:12:45 2012 (r229985) >> +++ head/lib/libutil/libutil.h Wed Jan 11 22:33:41 2012 (r229986) >> @@ -93,7 +93,7 @@ struct termios; >> struct winsize; >> >> __BEGIN_DECLS >> -char *auth_getval(const char *name); >> +char *auth_getval(const char *_name); > The _[a-z].* names are still in the app namespace. > > Only _[A-Z].* and __[a-z].* are reserved for the implementation. No, _[a-z].* is reserved for the implementation in file scope mainly for extern declarations). For example, _exit is reserved for the implementation, and _name is reserved for the implementation in exactly the same contexts as _exit is. This prevents the application #defining _name as '_this is not a C identifier', which would break the above. OTOH, _name is not reserved for the implementation in most other scopes, so applications can do almost anything with it except #define it or use it for a global or file-scope-static variable or function. style(9) even gives the exact rule (it says "an underscore" instead of "a single underscore", but uses only 1 in its example) to inhibit excessive underscoring in prototypes. Other details: - prototypes start a new scope so names in them are not subject to the file scope rules - similarly for struct scope. - the scopes naturally prevent -Wshadow warnings. E.g., names inside file-scope prototypes in implementation headers can't shadow application names, since the application names would have to be in file scope so they cannot have a single leading underscore. I haven't thought about all cases for this. Details from C99 (n869.txt): % 7.1.3 Reserved identifiers % % -- All identifiers that begin with an underscore are % always reserved for use as identifiers with file scope % in both the ordinary and tag name spaces. % ... % [#2] No other identifiers are reserved. If the program % declares or defines an identifier in a context in which it % is reserved (other than as allowed by 7.1.4), or defines a % reserved identifier as a macro name, the behavior is % undefined. I think we only need the reservation of _[a-z]* (actually _[a-z0-9]*) and the anti-definition rule for these to prove that the implementation's use of _[a-z0-9]* in non-file scope cannot conflict with any application use of _[a-z0-9]* any scope (can only be non-file scope). See <stdio.h> for old examples of using the precise rules for avoiding excessive underscoring, and complications in macros which require 2 underscores: - struct __sbuf has 2 underscores since it's in file scope - members in this struct and others have only 1 underscore since they are not in file scope - __sgetc() has 2 underscores, since it is used in getc(). getc() is used in function scope where _sgetc is in the application namespace. Thus, the implementation cannot use _sgetc here. - __sgetc() is implemented as an inline function. The names of parameters and local variables in this must have at least 1 underscore so that the application cannot #define them, and 1 is enough and only 1 is used for the same reasons as for parameter names in prototypes. - older implementations had an alternative definition of __sgetc() as a macro. Here no underscores are needed (and none are used) for the parameter names, since macro parameters have their own namespace and so cannot be corrupted by application #define's of their names which are now possible. These use the same single-undescored names for struct members. When I started writing this, I misremembered a complication here. I thought that some struct member names might need 2 underscores for such use. But there is no problem -- (p)->_w is protected enough by the single underscore in _w, in the same way as for inline functioms. Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120112235635.Y1663>