BruceS <> writes:
> On May 18, 1:49Â*pm, Ben Pfaff <b...@cs.stanford.edu> wrote:
>> BruceS <bruce...@hotmail.com> writes:
>> > On May 18, 6:41Â*am, Richard Heathfield <r...@see.sig.invalid> wrote:
>> >> Jeff wrote:
>> >> If you must have underscore decorations, use trailers, not leaders:
>>
>> >> #ifndef object_h__
>> >> #define object_h__
>>
>> > I've meant to ask about this one before. Â*I've picked up a (probably
>> > bad) habit of doing as above, from an employer where that was
>> > "standard". Â*Do these count as identifiers in the restricted space,
>> > even though they're macros?
>>
>> They are not reserved by C, but they are reserved by C++. Â*From
>> C++98:
>>
>> Â* Â* Â*17.4.3.1.2 Global names [lib.global.names]
>>
>> Â* Â* Â*1 Certain sets of names and function signatures are always
>> Â* Â* Â* Â*reserved to the implementation:
>>
>> Â* Â* Â* Â*- Each name that contains a double underscore (__) or begins
>> Â* Â* Â* Â* Â*with an underscore followed by an upper- case letter
>> Â* Â* Â* Â* Â*(2.11) is reserved to the implementation for any use.
>>
>> It's up to you whether to care about that, of course.
>
> No, I can't say I care about the restrictions in C++. I was just
> concerned about 7.1.3 Reserved identifiers, including "All identifiers
> that begin with an underscore and either an uppercase letter or
> another underscore are always reserved for any use." This would
> include the above usage if they count as identifiers. Now I look at
> 6.10.3 Macro replacement, item 2 "An identifier currently defined as a
> macro...", and it looks more conclusive. Macros count as identifiers,
> and identifiers such as __object_h are reserved. Am I missing
> something else? It wouldn't be the first time I'd misinterpreted part
> of the Standard.
No, you're not missing anything.
In C, all identifiers starting with either a double underscore or an
underscore followed by an uppercase letter are reserved for all purposes
(that includes macros). You should never declare such an identifier
yourself. For example, the implementation might have declared it as a
macro. Redefining it as a macro might break the implementation;
defining it as anything else might break your declaration. You're very
likely to get away with it in most cases (if your identifier doesn't
happen to collide with one used by the implementation), but you
shouldn't try. __FOO might work just fine today, but break with the
next release of your compiler.
Identifers starting with an underscore followed by something other than
a second underscore or an uppercase letter are reserved in fewer
contexts, but you should still avoid them (it's simpler to remember to
avoid leading underscores than to remember the odd cases that are
permitted).
(C++ additionally reserves identifiers with double underscores; this
does not apply to C, but if you want to avoid double underscores
anyway I certainly won't criticize you for it.)
Trailing underscores are harmless. (In C++, single trailing underscores
are harmless.) And they're not commonly used, which makes for a handy
convention for specialized purposes.
So this:
#ifdef object_h_
#define object_h_
/* ... */
#endif
is ok. Another convention I've seen is to use an uppercase name with a
leading H_:
#ifdef H_OBJECT
#define H_OBJECT
/* ... */
#endif
The H_ prefix avoids accidentally using an identifier starting with 'E'.
--
Keith Thompson (The_Other_Keith)
kst- <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"