9

According to the spec, global names with leading underscores are not allowed:

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

Does this also apply for names defined in a top-level anonymous namespace?

StackedCrooked
  • 34,653
  • 44
  • 154
  • 278
  • At BEST, it would be really, really poor form if you decided to use leading underscores on any of your variable names. – paulsm4 Jan 01 '12 at 06:16
  • 1
    @paulsm4 This is what the boost bind library does to define the argument placeholders (`_1`, `_2`, etc...). – StackedCrooked Jan 01 '12 at 06:26
  • 2
    An unnamed namespace is not particularly special; it is just an ordinary, uniquely-named namespace with an implicit using directive that injects its names into the enclosing namespace. However, there is an interesting question here: can a name brought into the global namespace via a using directive violate this rule? – James McNellis Jan 01 '12 at 08:37
  • @JamesMcNellis Indeed, that is the question I am asking. – StackedCrooked Jan 02 '12 at 15:57

2 Answers2

7

Names starting with a leading underscore followed by a non-capital alphanumeric character and not including a double underscore are only reserved in the global namespace. The reason for this is that on some systems certain names need to get a leading underscore or are already used by the underlying operating system and/or its C library. Names in an anonymous namespace don't have this problem.

That said, I'm always wondering why people are so keen to use ugly names! Unless I'm in standard library implementation mode (where I effectively have to use ugly names lest I conflict with user names) I'm always wondering if I'm doing something wrong using a leading underscore anywhere in my code! There are rare occasions where a leading underscore is needed (e.g. when calling _exit() or using std::bind()'s placeholders) but generally users shouldn't touch them: neither use nor define them.

sbi
  • 219,715
  • 46
  • 258
  • 445
Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
  • 2
    I fully agree with the sentiment expressed here. `+1` from me, I happen to know that the question arose out of a discussion in the [C++ chat room](http://chat.stackoverflow.com/rooms/10/loungec), not because Stacked meant to use those names, but since such questions are seen by potentially thousands of other users, I find it important to at least mention this. – sbi Jan 01 '12 at 12:39
  • I think it is a personal preference. I find `var_` ugly, but use `_var` all over my code (for "private" stuff, i.e. private members, TU-local entities like static globals). – Hedede Apr 27 '22 at 15:11
  • @Hedede Based on [lex.names] paragraph 3.2 identifiers with a leading `_` are only reserved in the global namespace. That is what the first sentence of my answer says (without standard reference, though). – Dietmar Kühl Apr 27 '22 at 17:01
  • @DietmarKühl I was referring to the second part of your answer (about ugly names). I just wanted to provide some reasoning. I use underscores for private stuff because `something._var` or `something->_var` looks ugly, and you instinctively start wondering whether you are doing something wrong. – Hedede Apr 27 '22 at 20:35
3

Yes. But that quote doesn't address that (as you know it yourself).

Here is what I think applies to that:

17.4.3.1.3 External linkage

3 . Each name having two consecutive underscores (2.11) is reserved to the implementation for use as a name with both extern "C" and extern "C++" linkage.

I think it applies to the variables declared with external linkage, in anonymous namespace, but it should be noted that it talks about double underscores. So:

namespace
{
   std::string __s1; //not allowed
   std::string _s2;  //allowed (allowed, as I understand)
}

A more general topic:

Community
  • 1
  • 1
Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • Also, `std::string _S3;` would not be allowed. – James McNellis Jan 01 '12 at 06:21
  • @JamesMcNellis: You mean `_s2` is allowed, but `_S3` is not (emphasizing the uppercase)? Which statement from spec forbids it? – Nawaz Jan 01 '12 at 06:24
  • See the first bullet point in the first citation in the accepted answer of the question to which you link. – James McNellis Jan 01 '12 at 06:26
  • @JamesMcNellis: I read that, and that talks about *global* names, as it is under section **Global names [lib.global.names]**. – Nawaz Jan 01 '12 at 06:31
  • 1
    The section header is irrelevant. The text stipulates that such names are reserved _for any use_. That includes use as macros, which precludes the use of such names in user code. – James McNellis Jan 01 '12 at 06:33
  • @JamesMcNellis: I think, it is not irrelevant, because the spec talks about categorically; first it talks about `17.4.3.1.1 Macro names`, then `17.4.3.1.2 Global names`, and finally, `17.4.3.1.3 External linkage`. – Nawaz Jan 01 '12 at 06:36
  • 2
    No, when it says _for any use_, it really means it. Take a look at your standard library's header files, especially those that define class and function templates. You will find that most names that aren't usable by user code (e.g. include guards, other macros, template parameter names, variable names, etc.) are of the form `__x` or `_X`. This is because such names are reserved to the implementation _for any use_. If such names were not reserved _for any use_, then user code could define those names as macros and the standard library wouldn't work at all. – James McNellis Jan 01 '12 at 06:50
  • This question is about names that begin with a single leading underscore. I think I quoted the relevant section. What I want to know is whether a name declared in a global anonymous namespace should be considered global or not. – StackedCrooked Jan 01 '12 at 07:26