Topic: class member name beginning with underscore


Author: hansen@pegasus.bl-els.att.com (-Tony L. Hansen)
Date: Wed, 20 Apr 1994 18:02:49 GMT
Raw View
< From: shepherd@debussy.sbi.com (Marc Shepherd)
<
< I've read that in ANSI/ISO standard C++, identifiers beginning with an
< underscore are banned.  Does that include class members?  That is, if a
< class is defined:
<
< class Foo
< {
<   public:
<  int _class_member;
<  double _another_member;
< };
<
< is the program non-conforming?

Actually, identifiers beginning with an underscore and followed by a capital
letter or underscore are banned by ANSI/ISO C. More accurately, they are
reserved to the implementation. Therefore, the identifiers you use above are
okay. Note that C++ further reserves all identifiers which have a doubled
underscore (__).

Hope this helps.

     Tony Hansen
       hansen@pegasus.att.com, tony@attmail.com
    att!pegasus!hansen, attmail!tony




Author: bkline%occs.nlm.nih.gov (Bob Kline)
Date: Sat, 23 Apr 94 22:41:00 GMT
Raw View
David Sachs (b91926@fsgi01.fnal.gov) wrote:
: shepherd@debussy.sbi.com (Marc Shepherd) writes:

: >I've read that in ANSI/ISO standard C++, identifiers beginning with an
: >underscore are banned.  Does that include class members?  That is, if a
: >class is defined:

: > class Foo
: > {
: >   public:
: >  int _class_member;
: >  double _another_member;
: > };

: >is the program non-conforming?

: A program containing such identifiers is non-portable, but will probably
: work on many systems. The ARM (and presumably the forthcoming standard)
: reserves identifiers containing "__" or starting wih "_" for use by
: the language implementors. Expect to see internally used libary entry points
: with such names.

I wouldn't assume that the forthcoming standard will be as sloppy as
the ARM is in the passage you cite.  If C++ follows the lead of the
C standard, which addresses this issue much more explicitly, the
reservation of names with a leading underscore applies only to names
that have external linkage, which would not apply to the original
poster's example.  Class member names run no risk of conflict with
"internally used lib[r]ary entry points."

--
/*----------------------------------------------------------------------*/
/* Bob Kline                                           CSI Technologies */
/* bkline@smtp.csof.com                        Corporate Software, Inc. */
/* voice: (703) 522-0820                            fax: (703) 522-5407 */
/*----------------------------------------------------------------------*/




Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: Tue, 26 Apr 1994 22:13:42 GMT
Raw View
maxtal@physics.su.OZ.AU (John Max Skaller) writes:

>bkline%occs.nlm.nih.gov (Bob Kline) writes:
>>David Sachs (b91926@fsgi01.fnal.gov) wrote:
>>: shepherd@debussy.sbi.com (Marc Shepherd) writes:
>>
>>: >I've read that in ANSI/ISO standard C++, identifiers beginning with an
>>: >underscore are banned.  Does that include class members?
>>
>>: The ARM (and presumably the forthcoming standard)
>>: reserves identifiers containing "__" or starting with "_" for use by
>>: the language implementors.
>>
>>I wouldn't assume that the forthcoming standard will be as sloppy as
>>the ARM is in the passage you cite.  If C++ follows the lead of the
>>C standard, which addresses this issue much more explicitly, the
>>reservation of names with a leading underscore applies only to names
>>that have external linkage, which would not apply to the original
>>poster's example.
>
> I'm surprised a bit. Names starting with underscores
>(or is that two underscores?) need to be globally reserved for
>implementors, end of story.

That's the point - it should be *two* underscores.

>It should have nothing to do
>with external linkage. The implementor may make these things
>keywords or macros. Hence
>
> _far, _near
>
>in DOS implementations.

But the point is that _far and _near are NOT conformant to the ANSI C
standard, and standard-compliant compilers must DISABLE any such
keywords when invoked in standard-complaint mode.  __far and __near
would be ok, but for some unknown stupid reason DOS compiler vendors
don't use these.

The following is a strictly conforming ANSI C program.
I hope the C++ committee ensures that it is also a legal C++ program.

 int main() {
  int _near, _far;
  _near = _far = 0;
  return 0;
 }

--
Fergus Henderson - fjh@munta.cs.mu.oz.au




Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Sun, 24 Apr 1994 23:28:06 GMT
Raw View
In article <1994Apr23.224100.25555@nlm.nih.gov> bkline%occs.nlm.nih.gov (Bob Kline) writes:
>David Sachs (b91926@fsgi01.fnal.gov) wrote:
>: shepherd@debussy.sbi.com (Marc Shepherd) writes:
>
>: >I've read that in ANSI/ISO standard C++, identifiers beginning with an
>: >underscore are banned.  Does that include class members?  That is, if a
>: >class is defined:
>
>: A program containing such identifiers is non-portable, but will probably
>: work on many systems. The ARM (and presumably the forthcoming standard)
>: reserves identifiers containing "__" or starting wih "_" for use by
>: the language implementors. Expect to see internally used libary entry points
>: with such names.
>
>I wouldn't assume that the forthcoming standard will be as sloppy as
>the ARM is in the passage you cite.  If C++ follows the lead of the
>C standard, which addresses this issue much more explicitly, the
>reservation of names with a leading underscore applies only to names
>that have external linkage, which would not apply to the original
>poster's example.  Class member names run no risk of conflict with
>"internally used lib[r]ary entry points."

 I'm surprised a bit. Names starting with underscores
(or is that two underscores?) need to be globally reserved for
implementors, end of story.  It should have nothing to do
with external linkage. The implementor may make these things
keywords or macros. Hence

 _far, _near

in DOS implementations. However, names of global functions
are NOT reserved as an identifier in C++, because we have namespaces.
The 'std' namespace is reserved. You can define 'strlen' in your
own namespace without fear. Dont do it yet -- wait until
your compiler supports namespaces!

And be wary of C library functions that can be macros. Namespaces
dont protect them.



--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,      CSERVE:10236.1703
        6 MacKay St ASHFIELD,     Mem: SA IT/9/22,SC22/WG21
        NSW 2131, AUSTRALIA




Author: daniels@biles.com (Brad Daniels)
Date: Wed, 27 Apr 1994 14:43:09 GMT
Raw View
In article <9411708.28901@mulga.cs.mu.oz.au>,
Fergus Henderson <fjh@munta.cs.mu.OZ.AU> wrote:
>maxtal@physics.su.OZ.AU (John Max Skaller) writes:
...
>> I'm surprised a bit. Names starting with underscores
>>(or is that two underscores?) need to be globally reserved for
>>implementors, end of story.
>
>That's the point - it should be *two* underscores.
>
>>It should have nothing to do
>>with external linkage. The implementor may make these things
>>keywords or macros. Hence
>>
>> _far, _near
>>
>>in DOS implementations.
>
>But the point is that _far and _near are NOT conformant to the ANSI C
>standard, and standard-compliant compilers must DISABLE any such
>keywords when invoked in standard-complaint mode.  __far and __near
>would be ok, but for some unknown stupid reason DOS compiler vendors
>don't use these.

It gets even a bit weirder than that.  ANSI C does not require case
sensitivity for symbols with external linkage (as a concession to VMS
and other systems with case-insensitive linkers.)  The ANSI/ISO C standard
reserves symbols starting with an underscore followed by either a second
underscore *or an uppercase letter*.  This means that "_foo" is a legitimate
identifier for local variables, structure members, etc., but that it must
be considered reserved when used as an external identifier (since you can't
guarantee it's differentiable from _FOO, which is a reserved identifier.)

- Brad
------------------------------------------------------------------------
+ Brad Daniels                  | "Let others praise ancient times;    +
+ Biles and Associates          |  I am glad I was born in these."     +
+ These are my views, not B&A's |           - Ovid (43 B.C. - 17 A.D.) +
------------------------------------------------------------------------




Author: jamshid@ses.com (Jamshid Afshar)
Date: Wed, 20 Apr 1994 00:16:05 GMT
Raw View
In article <2on187$7gq@fsgi01.fnal.gov>,
David Sachs <b91926@fsgi01.fnal.gov> wrote:
>shepherd@debussy.sbi.com (Marc Shepherd) writes:
>
>>I've read that in ANSI/ISO standard C++, identifiers beginning with an
>>underscore are banned.  Does that include class members?  [...]
>> class Foo {
>>  int _class_member;
>> };
>
>A program containing such identifiers is non-portable, but will probably
>work on many systems. The ARM (and presumably the forthcoming standard)
>reserves identifiers containing "__" or starting wih "_" for use by
>the language implementors. Expect to see internally used libary entry points
>with such names.

That's not entirely correct.  The ARM reserves all identifiers
beginning with a double underscore for any use by the implementation.
The commentary further recommends that users should avoid identifiers
beginning with a single underscore.

The ANSI/ISO Working Paper (17.1.4 of the January 1994 copy and
17.4.1.2.1 of the June 1993 copy) and the ANSI C standard all are very
clear about the subject.  Member names beginning with a single
underscore followed by a *lower-case* letter are fine.  In file scope,
however, such names are reserved for the implementation.  This means
you can use _foo as a data member or member function, but you could
not define a global or static _foo function or variable.

Btw, names beginning with single underscore followed by an uppercase
letter are, like names beginning with double underscores, reserved for
any use by the implementation.

Btw2, BC++ 4.0 has an interesting bug.  It's <float.h> defines the
variable _huge_flt to be the largest float value.  That's fine.  But,
it also defines FLT_MAX in <limits.h> to _huge_flt.  This means that
if you defined a member named _huge_flt, you'll run into problems:

 #include <float.h>
 #include <limits.h>

 class Foo {
    float _huge_flt;
 public:
    float set(float d = FLT_MAX);  // BC++ gives error
 };

The BC++ headers can be corrected (in accordance with the ANSI/ISO
Working Paper) by renaming the variable _huge_flt to __huge_flt or by
defined FLT_MAX as a const float instead of a macro.  I thought this
was interesting because the problem doesn't pop up in C because it
didn't have a class scope.

That doesn't change my opinion on preceding data member names with an
underscore.  Here's an article I wrote on the subject a couple of
months ago:

------

From: jamshid@ses.com (Jamshid Afshar)
Subject: Re: Is "_variable" dangerous?
Message-ID: <CLMs49.KH5@ses.com>
Summary: it's legal and `_far' no more dangerous than `far'
Organization: SES, Inc., Austin, TX, USA
Date: Tue, 22 Feb 1994 14:55:20 GMT

In article <1994Feb14.122536.25688@huldra.tdata.no>,
Geir Hansen <geha@huldra.tdata.no> wrote:
>Mike Campbell (mcampbel@offenbach.sbi.com) wrote:
>:I have a friend at work who uses a ``coding style'' wherein he prepends an
>:underscore to all private class member variables.Is this in danger of somehow
>:conflicting with internal names a compiler might use?  I seem to rememeber
>:someone telling me long ago,``Don't do that'',for variables in C, but I don't
>:remember exactly why, or what the circumstances were.
>:Is this a "Bad Thing" in C++?  (*Or* in C?)

I don't think using "_member_name" is a bad idea.  I think it is very
important that C/C++ users understand what identifier names are
available to them in what situations.  Of course, its probably easier
to just remember that any variable beginning with an underscore or
containing two consecutive underscores anywhere is off-limits, but I
don't think your friend should be forced to change his coding style,
nor should we tolerate compiler vendors who invade our name space.

Here's a list of reserved identifiers in C++ (using shell wildcards).
I think all of these rules also apply to C, except maybe the
consecutive underscores rule.  Some headers reserve a range of other
identifiers (eg, <errno.h> reserves E[A-Z_]*).  Also, POSIX headers
reserve *_t, among other things.

 Identifiers When reserved by the implementation
 ----------- -----------------------------------
 _[A-Z_]* anytime for anything (eg, macros, special keywords)
 *__*  identifiers with extern C or C++ linkage
 _*  file scope (eg, function or class names)

Therefore, _[a-z0-9]* makes a perfectly legal class member name,
although _MemberName does not.

>The ANSI comittee for C and C++ states that compiler vendors can use
>a double underscore for their own things. For example Borland and
>Microsoft uses "__far" and "__near" as reserved keywords in their
>compilers. If you use only one underscore, you must be aware that these
>compilers add a preceeding extra underscore, so that one underscore
>becomes two.

Err, no.  The fact that a compiler "mangles" a C or C++ identifier
name and adds a preceding underscore cannot affect whether that
identifier belongs to the user or implemenation name space.

>I can also imagine that the compiler vendors may have
>several "secret" undocumented keywords (I wouldn't be surprised), which
>you may be unfortunate to "hit" when you use the mentioned coding style.
>The thumb of rule is "avoid preceeding underscores".

I think this rule of thumb (which is very common) is overly strict and
does not avoid enough name space clashes to be worth restricting a
person's style.  I see too many invasions of the implementation's
namespace like using the macro name _FILE_H in a header #ifndef
wrapper or defining a function whose name begins with `str'.  I would
make sure a coding style avoided all the names ANSI reserves before
worrying about broken compilers which invade the users' name space.

And no, I'm not just being pedantic when I use _member_name.  The most
common reason cited to avoid such names is MS-DOS compilers which
define the keywords _far, _near, _huge.  These compilers give an error
for the following (legal!) class definition:

 class Distance {
    int _far;
    void (*_near)();
 };

But, at least two major MS-DOS compilers (BC++ and Watcom C++) give
errors even if you remove the leading underscore:

 class Distance { // BC++ and Watcom C++ still give error
    int far;
    void (*near)();
 };

BC++ accepts *either* version code when compiling in strict ANSI mode.
Unfortunately, you can't use some BC++ headers or do some common
things required by an MS-DOS program in strict ANSI mode.  A good
MS-DOS compiler would only define the keyword `__far' and not the
keywords `far' or `_far'.

My point is that `_member_name' is allowed by ANSI and avoiding such
identifiers does not in practice avoid compiler keyword clashes.  If
your coding style, out of simplicity, recommends avoiding any names
beginning with an underscore, that's fine with me as long as you also
avoid all the other names that ANSI (and maybe even POSIX) really does
reserve for the implementation.

Jamshid Afshar
jamshid@ses.com




Author: shepherd@debussy.sbi.com (Marc Shepherd)
Date: Thu, 14 Apr 1994 21:05:22 GMT
Raw View
I've read that in ANSI/ISO standard C++, identifiers beginning with an
underscore are banned.  Does that include class members?  That is, if a
class is defined:

 class Foo
 {
   public:
  int _class_member;
  double _another_member;
 };

is the program non-conforming?

Thanks.

---
Marc Shepherd
Salomon Brothers Inc
mshepherd@mhfl   The opinions I express are no one's but mine!





Author: b91926@fsgi01.fnal.gov (David Sachs)
Date: 15 Apr 1994 16:33:59 -0500
Raw View
shepherd@debussy.sbi.com (Marc Shepherd) writes:

>I've read that in ANSI/ISO standard C++, identifiers beginning with an
>underscore are banned.  Does that include class members?  That is, if a
>class is defined:

> class Foo
> {
>   public:
>  int _class_member;
>  double _another_member;
> };

>is the program non-conforming?

A program containing such identifiers is non-portable, but will probably
work on many systems. The ARM (and presumably the forthcoming standard)
reserves identifiers containing "__" or starting wih "_" for use by
the language implementors. Expect to see internally used libary entry points
with such names.