underscores in class member names

B

BRIAN VICKERY

I've heard that some compilers reserve the '_' starting a symbol for system
variables/symbols. I can not find this documented anywhere (so far). I've
used an '_' at the end of member variables (ie. Uint16 bar_; ) to
distinquish private fields, but this does not stand out as much as if the
'_' were at the begginning of the name as in the following class
declaration.

class Foo {
private:
Uint16 _baz;
Uint32 _bar;

public:
....
};
 
R

Rolf Magnus

BRIAN said:
I've heard that some compilers reserve the '_' starting a symbol for
system variables/symbols.

The C++ language reserves some of them, like e.g. those that begin with
an underscore followed by an uppercase letter and those that contain
two consecutive underscores.
I can not find this documented anywhere (so far).
I've used an '_' at the end of member variables (ie. Uint16 bar_; )
to distinquish private fields,

That's quite common practise.
but this does not stand out as much as if the '_' were at the
begginning of the name as in the following class
declaration.

class Foo {
private:
Uint16 _baz;
Uint32 _bar;

public:
....
};

I think those shold be fine.
 
S

Sumit Rajan

BRIAN VICKERY said:
I've heard that some compilers reserve the '_' starting a symbol for system
variables/symbols. I can not find this documented anywhere (so far). I've
used an '_' at the end of member variables (ie. Uint16 bar_; ) to
distinquish private fields, but this does not stand out as much as if the
'_' were at the begginning of the name as in the following class
declaration.

class Foo {
private:
Uint16 _baz;
Uint32 _bar;

public:
....
};


From 17.4.3.1.2 of the Standard:



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 uppercase letter (2.11) is reserved to the
implementation for any use.

- Each name that begins with an underscore is reserved to the implementation
for use as a name in the global namespace.
 
R

Rob Williscroft

BRIAN VICKERY wrote in
I've heard that some compilers reserve the '_' starting a symbol for
system variables/symbols. I can not find this documented anywhere (so
far). I've used an '_' at the end of member variables (ie. Uint16
bar_; ) to distinquish private fields, but this does not stand out as
much as if the '_' were at the begginning of the name as in the
following class declaration.

class Foo {
private:
Uint16 _baz;
Uint32 _bar;

public:
....
};

Am identifier with single leading undersore is reserved for the
implementation if:

Its followed by an uppercase letter (anywhere).

Its followed by another underscore (anywhere), in fact *all* identifiers
that *contain* 2 or more *consecutive* underscores are reserved.

Its declared at global namespace scope, i.e its a macro or it
*isn't* declared within an namespace, class, struct or union or it
*isn't* a paramiter name or a local variable name.

Also IIUC it shouldn't be a declared extern "C".

So you usage for member identifiers is Ok.

Nobody really likes it though and most people can't be bothered to
remember all the rules, so they will probably complain that your using a
reserved identifier anyway, so I'd suggest m_baz or some such thing.

Rob.
 
J

Jonathan Turkanis

Rob Williscroft said:
Am identifier with single leading undersore is reserved for the
implementation if:

Its followed by an uppercase letter (anywhere).

Its followed by another underscore (anywhere), in fact *all* identifiers
that *contain* 2 or more *consecutive* underscores are reserved.

Its declared at global namespace scope, i.e its a macro or it
*isn't* declared within an namespace, class, struct or union or it
*isn't* a paramiter name or a local variable name.

Also IIUC it shouldn't be a declared extern "C".

So you usage for member identifiers is Ok.

Nobody really likes it though and most people can't be bothered to
remember all the rules, so they will probably complain that your using a
reserved identifier anyway, so I'd suggest m_baz or some such thing.

I'm familiar with the language from the standard, but it sounds a bit
ambiguous:

"reserved to the implementation for use as a name in the global
namespace"

could mean:

(i) reserved to the implementation; also, must be global,

or

(ii) reserved to the implementation if used in the global namespace

Why do you prefer (i)? Is this known to be the correct interpretation?

Jonathan
 
B

Bob Hairgrove

Check 17.4.3.1.2 of the C++ standard first.

Stroustrup says "never" ... (see p. 81 of the 3rd edition, "The C++
Programming Language).
 
R

Rob Williscroft

Jonathan Turkanis wrote in berlin.de:
I'm familiar with the language from the standard, but it sounds a bit
ambiguous:

"reserved to the implementation for use as a name in the global
namespace"

could mean:

(i) reserved to the implementation; also, must be global,

This would be the same as reserved ... everywhere. The "must be global"
would be unnessasery additional info'.
or

(ii) reserved to the implementation if used in the global namespace

[from elswhere]
I meant (ii) here.
Why do you prefer (i)? Is this known to be the correct interpretation?

Sorry but (i) doesn't make any sense to me.

_lowecase identifiers are used to support the C standard library and
meny C++ implementation's just use the C library as-is, and most
allow you to link with C code that will link in the C library.

C++ needs another set of identifiers _Uppercase so it doesn't stomp
on the _lowecase ones and also the double underscore rule for name
mangaling. This allows a C++ compiler to compile via a C compiler
as meny still do.

Rob.
 
G

Graham Dumpleton

Rob Williscroft said:
BRIAN VICKERY wrote in

Am identifier with single leading undersore is reserved for the
implementation if:

Its followed by an uppercase letter (anywhere).

From memory, Microsoft C++ used to (not sure now), define a special
keyword called "_except". If you tried to use that name, even as a
member variable of a class, the compiler would spit the dummy.

Thus, regardless of what the standard for C++ says, don't necessarily
expect Microsoft to adhere to it. :)
 
R

Rob Williscroft

Graham Dumpleton wrote in @posting.google.com:
From memory, Microsoft C++ used to (not sure now), define a special
keyword called "_except". If you tried to use that name, even as a
member variable of a class, the compiler would spit the dummy.

yes also things like _far, _near, _try all of which are extemsion
keywords
Thus, regardless of what the standard for C++ says, don't necessarily
expect Microsoft to adhere to it. :)

Well did MS introduce the keyword before or after the standard
came out (1998). Certainly I've noticed that all of the extension
keywords I've come accross reciently have had 2 leading underscores
__declspec.


Rob.
 
J

Jonathan Turkanis

Rob Williscroft said:
This would be the same as reserved ... everywhere. The "must be global"
would be unnessasery additional info'.

Unnecessary info for users, maybe, but not for implementers.

Maybe you mean it would be an 'unneccessary additional restriction'?
Are you sure that C++ doesn't have any of these? ;-)

Jonathan
 
R

Rob Williscroft

Jonathan Turkanis wrote in berlin.de:
Unnecessary info for users, maybe, but not for implementers.

How would it help an implementer, the standard tells implementors
what they have to implement not *how*, "must be global" could
only be related to how.
Maybe you mean it would be an 'unneccessary additional restriction'?

It isn't a restriction, its saying that _lowercase *must* be a global
namespace identifier, i.e. its telling an implementor some details
about *how* to implement.

[snip]

Rob.
 
J

Jonathan Turkanis

Rob Williscroft said:
How would it help an implementer, the standard tells implementors
what they have to implement not *how*, "must be global" could
only be related to how.

Did I say 'helpful'? I said 'necessary': if (i) is correct, then it
constitutes necessary information for implementers.
restriction'?

It isn't a restriction, its saying that _lowercase *must* be a global
namespace identifier, i.e. its telling an implementor some details
about *how* to implement.

What distinction are you trying to make? I don't see how a requirement
that such identifiers -- if used by an implementation -- must be
global, isn't a restriction. True, the standard tries to give
implementers broad discretion, yet it also puts quite a few
constraints on implementations.

Maybe you should try to find some evidence in favor of your
interpretation. I never said it was wrong, by the way. I just asked
you to support it.

Jonathan
 
R

Rob Williscroft

Jonathan Turkanis wrote in berlin.de:
Did I say 'helpful'? I said 'necessary': if (i) is correct, then it
constitutes necessary information for implementers.

My apologees, I should have consulted the standard when you first said:
I'm familiar with the language from the standard, but it sounds a bit
ambiguous:

"reserved to the implementation for use as a name in the global
namespace"

could mean:

(i) reserved to the implementation; also, must be global,

This section (17.4.3) is describing constraints on programmes.
However your rewording with hindsight appears to be as if your reading
the section as constraining implementation's.
What distinction are you trying to make? I don't see how a requirement
that such identifiers -- if used by an implementation -- must be
global, isn't a restriction.

Indeed, implementors arn't allowed to use _lowercase identifiers
other than in the global namespace (or in std).

I interpreted you originaly as suggesting *nobody* could use such
identifiers other than in the global namespace and only
implementors can use them there.
True, the standard tries to give
implementers broad discretion, yet it also puts quite a few
constraints on implementations.

Maybe you should try to find some evidence in favor of your
interpretation. I never said it was wrong, by the way. I just asked
you to support it.

There is only one peice evidence available, I presume since you
quoted from it, that you've read it. It helps if you read the all
of "17.4.3 Constraints on programs", here's the relevent quote:

17.4.3.1.2 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 uppercase letter (2.11) is reserved
to the implementation for any use.

— Each name that begins with an underscore is reserved to the
implementation for use as a name in the global namespace.165)

165) Such names are also reserved in namespace ::std (17.4.3.1).

The second bullet is clearly saying that implementation's can use
identifiers such as _lowercase at in the global namespace so
a conforming programme may not.

The note 165) tells us we can't put such identifiers in namespace std
but we can't do that anyway.

Rob.
 
J

Jack Klein

I'm familiar with the language from the standard, but it sounds a bit
ambiguous:

"reserved to the implementation for use as a name in the global
namespace"

could mean:

(i) reserved to the implementation; also, must be global,

or

(ii) reserved to the implementation if used in the global namespace

Why do you prefer (i)? Is this known to be the correct interpretation?

Jonathan

Your confusion, and this wording, is caused by C++ adopting a C
restriction but applying new terminology.

C reserves the leading underscore+upper case, and leading double
underscore (but not embedded double underscore, that's a C++ addition)
in all contexts.

Then it reserves leading underscore+lower case at file scope. The
problem with C++ duplicating this restriction is... there is NO SUCH
THING as "file scope" in the standard C++. The phrase literally does
not exist in the standard.

What is file scope in C has been expanded into the concept of
namespace scope in C++. Things that are defined or declared outside
of a function in C++ are either inside a (named or anonymous)
namespace, concepts that do not exist in C, or they are at the top
level, what C calls "file scope" and C++ calls the global namespace.

Note that it makes no difference whether the "file scope"/"global
namespace" identifiers have external linkage or not, even with
internal linkage they can conflict with things the compiler defines in
its header files, or even pre-defined helper functions that it calls
directly.

Don't confuse the global namespace in C++ with the concept of global
variables. It really means pretty much exactly the same thing as file
scope in C.
 
J

Jonathan Turkanis

Jack Klein said:
Your confusion, and this wording, is caused by C++ adopting a C
restriction but applying new terminology.

C reserves the leading underscore+upper case, and leading double
underscore (but not embedded double underscore, that's a C++ addition)
in all contexts.

Then it reserves leading underscore+lower case at file scope. The
problem with C++ duplicating this restriction is... there is NO SUCH
THING as "file scope" in the standard C++. The phrase literally does
not exist in the standard.

What is file scope in C has been expanded into the concept of
namespace scope in C++. Things that are defined or declared outside
of a function in C++ are either inside a (named or anonymous)
namespace, concepts that do not exist in C, or they are at the top
level, what C calls "file scope" and C++ calls the global namespace.

Note that it makes no difference whether the "file scope"/"global
namespace" identifiers have external linkage or not, even with
internal linkage they can conflict with things the compiler defines in
its header files, or even pre-defined helper functions that it calls
directly.

Don't confuse the global namespace in C++ with the concept of global
variables. It really means pretty much exactly the same thing as file
scope in C.

Thank you for your historical perspective. I don't believe I was
confusing global variables with the global namespace. I was using
'global' as shorthand for 'in the global namespace' because we were
focusing on a different issue. The question was whether member
variable names with single leading underscores not followed by an
uppercase letter are legal in user code.

Looking at the second item of 17.4.3.1.2/1,

Each name that begins with an underscore is reserved to the
implementation for use as a name in the global namespace,

I noted that there was a plausible reading according to which such a
use would be prohibited. Namely, it could be held to say that such
names are reserved for use by the implementation -- so that they
cannot be used at all in user code -- and *additionally* the
implementation must use such names, if it choses to use them at all,
in the global namespace.

Jonathan
 
K

Keith H Duggar

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 uppercase letter (2.11) is reserved to the
implementation for any use.

- Each name that begins with an underscore is reserved to the implementation
for use as a name in the global namespace.

Can someone explain to me *what* or *who* is or qualifies as an
implementation? For example, SGI's STL library contains _Uppercase and
__doubleunder names. Why does the SGI company or programmer in SGI
have the right to be an *implementation* but I do not? Why are not my
libraries just as *implementation* worthy as any other programmer.

Also, can someone explain to me by what mechanisms (besides a macro)
the use of these underscores names within a class or namespace I
create can conflict with a C++ implementation.
 
P

Phlip

Keith said:
Can someone explain to me *what* or *who* is or qualifies as an
implementation? For example, SGI's STL library contains _Uppercase and
__doubleunder names. Why does the SGI company or programmer in SGI
have the right to be an *implementation* but I do not? Why are not my
libraries just as *implementation* worthy as any other programmer.

What does the S in STL stand for?
Also, can someone explain to me by what mechanisms (besides a macro)
the use of these underscores names within a class or namespace I
create can conflict with a C++ implementation.

typedef int __doubleunder;

std::vector<int> yo;

Pretend that std::vector depended on a variable called __doubleunder, but
your typedef made its usage look like a type.

(I'm stuck on this one too - just don't do it!)
 
R

Rolf Magnus

Keith said:
Can someone explain to me *what* or *who* is or qualifies as an
implementation?

Anything that implements the (or part of the) C++ standard.
For example, SGI's STL library contains _Uppercase and
__doubleunder names. Why does the SGI company or programmer in SGI
have the right to be an *implementation* but I do not?

Probably because they are implementing the standard library (which is
part of C++ and thus part of an implementation of it) and you don't.
Why are not my libraries just as *implementation* worthy as any other
programmer.

They are not implementations of the standard.
Also, can someone explain to me by what mechanisms (besides a macro)
the use of these underscores names within a class or namespace I
create can conflict with a C++ implementation.

One example is the name mangling. In C++, several functions with the
same name can exist in different namespaces or as members of different
classes or just as overloads with different number and types of
arguments. So there is typically a scheme that translates those
function names to internal names that contain all that information so
the linker can find the functions. Those internal names are often such
reserved names, so if you use those, they can conflict with other code.
 
R

Rolf Magnus

Rolf said:
One example is the name mangling. In C++, several functions with the
same name can exist in different namespaces or as members of different
classes or just as overloads with different number and types of
arguments. So there is typically a scheme that translates those
function names to internal names that contain all that information so
the linker can find the functions. Those internal names are often such
reserved names, so if you use those, they can conflict with other
code.

Just for a practical example of this. You can't produce an executable
from the following code with e.g. g++ 3.3.2:

int _Z4testv;

void test() {};

int main()
{
test();
}

The reason is that the internal mangled name for the function test is
_Z4testv, so there is a naming conflict with the global variable. The
error message looks like this:

/tmp/cckaLQYy.s: Assembler messages:
/tmp/cckaLQYy.s:13: Error: symbol `_Z4testv' is already defined
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top