Why Do People Use _ (Double Underscore) So Much in C++

Why do people use __ (double underscore) so much in C++

From Programming in C++, Rules and Recommendations :

The use of two underscores (`__') in identifiers is reserved for the compiler's internal use according to the ANSI-C standard.

Underscores (`_') are often used in names of library functions (such as "_main" and "_exit"). In order to avoid collisions, do not begin an identifier with an underscore.

Meaning of double underscore in the beginning

From GNU's manual:

In addition to the names documented in this manual, reserved names
include all external identifiers (global functions and variables) that
begin with an underscore (‘_’) and all identifiers regardless of use
that begin with either two underscores or an underscore followed by a
capital letter are reserved names. This is so that the library and
header files can define functions, variables, and macros for internal
purposes without risk of conflict with names in user programs.

This is a convention which is also used by C and C++ vendors.

Where to finding the precise meaning of a double underscore variable

There is no general rule for determining the meaning of an identifier (not necessarily a variable name) whose name starts with two underscores (or with an underscore and an uppercase letter; those are also reserved to the implementation).

Some such identifiers are defined by the C standard. Examples are __FILE__, __LINE__, __STDC__, __STDC_VERSION__ (all predefined macros) and __func__ (not a macro but an implicitly declared identifier in each function).

You can find a draft of the C standard at http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf. Note that the PDF encodes double underscores in an odd way so they're displayed properly, so a search for __STDC__ will likely fail. You can search for _STDC_ instead.

Any such identifiers not mentioned in the standard may be defined by the implementation (either the compiler or the runtime library). Consult your implementation's documentation. Be aware that some such identifiers might not be documented if the implementation uses them only for its own internal purposes.

As for __VA_ARGS__, that's defined by the C standard, in section 6.10.3.1. It's used in variadic macros (macros that can accept a variable number of arguments). It's also documented in the gcc manual.

What does a double underscore mean in a variable name in the C language?

It means it's a system-reserved name. The C standard says that all names beginning with two underscore, or underscore and capital letter, are reserved for the use of the system or compiler and should not be defined in application code.

Why do some functions in C have an underscore prefix?

The underscore prefix is reserved for functions and types used by the compiler and standard library. The standard library can use these names freely because they will never conflict with correct user programs.

The other side to this is that you are not allowed to define names that begin with an underscore.

Well, that is the gist of the rule. The actual rule is this:

  • You cannot define any identifiers in global scope whose names begin with an underscore, because these may conflict with hidden (private) library definitions. So this is invalid in your code:

    #ifndef _my_header_h_
    #define _my_header_h_ // wrong
    int _x; // wrong
    float _my_function(void); // wrong
    #endif

    But this is valid:

    #ifndef my_header_h
    #define my_header_h // ok
    int x; // ok
    float my_function(void) { // ok
    int _x = 3; // ok in function
    }
    struct my_struct {
    int _x; // ok inside structure
    };
    #endif
  • You cannot define any identifiers in any scope whose names begin with two underscores, or one underscore followed by a capital letter. So this is invalid:

    struct my_struct {
    int _Field; // Wrong!
    int __field; // Wrong!
    };
    void my_function(void) {
    int _X; // Wrong!
    int __y; // Wrong!
    }

    But this is okay:

    struct my_struct {
    int _field; // okay
    };
    void my_function(void) {
    int _x; // okay
    }

There are actually a few more rules, just to make things complicated, but the ones above are the most often violated and the easiest to remember.

What is this double underscore in Cocoa

Neither the C compiler nor the Objective-C compiler treats variable names with leading underscores any differently than any other variable name. A single or double leading underscore is simply a convention and effectively forms a namespace, much like the NS prefix used in Cocoa classes like NSString.

Looking at the SQLiteBooks code, MasterViewController.m defines this static global variable:

// Manage the editing view controller from this class so it can be easily accessed from both the detail and add controllers.
static EditingViewController *__editingViewController = nil;

So my guess is that the author of SQLiteBooks uses a double leading underscore to indicate a global variable.

C compilers (and by extension Objective-C) reserve names beginning with two underscores and a capital letter for use by the compiler vendor, giving them a reserved namespace to use for global variables and functions used to implement standard libraries, or to introduce new non-standard keywords like __block.

While the SQLiteBooks code is technically valid, it's too easily confused with the reserved namespace in my opinion. If you do reuse that code, I'd recommend renaming that variable (Xcode has a very nice rename refactoring that will do it automatically for you).

Use of double underscore in C

Identifiers that begin with two underscores or an underscore and a capital letter are reserved by the C standard and should not be used in your own code, cf. ISO 9899:2011 §7.1.3 ¶1 #1:

7.1.3 Reserved identifiers

1 Each header declares or defines all identifiers listed in its associated subclause, and optionally declares or defines identifiers listed in its associated future library directions subclause and identifiers which are always reserved either for any use or for use as file scope identifiers.

  • All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use.
  • 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.
  • Each macro name in any of the following subclauses (including the future library directions) is reserved for use as specified if any of its associated headers is included; unless explicitly stated otherwise (see 7.1.4).
  • All identifiers with external linkage in any of the following subclauses (including the future library directions) and errno are always reserved for use as identifiers with external linkage.184)
  • Each identifier with file scope listed in any of the following subclauses (including the future library directions) is reserved for use as a macro name and as an identifier with file scope in the same name space if any of its associated headers is included.

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.

3 If the program removes (with #undef) any macro definition of an identifier in the first group listed above, the behavior is undefined.


184) The list of reserved identifiers with external linkage includes math_errhandling, setjm, va_copy, and va_end.

For double underscores inside names: These are hard to tell apart from single underscores in many typefaces and lead to confusion. I recommend you to avoid doing that.

use _ and __ in C programs

Here's what the C standard says (section 7.1.3):

  • All identifiers that begin with an underscore and either an uppercase letter or another
    underscore are always reserved for any use.
  • 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.

(The section goes on to list specific identifiers and sets of identifiers reserved by certain standard headers.)

What this means is that for example, the implementation (either the compiler or a standard header) can use the name __FOO for anything it likes. If you define that identifier in your own code, your program's behavior is undefined. If you're "lucky", you'll be using an implementation that doesn't happen to define it, and your program will work as expected.

This means you simply should not define any such identifiers in your own code (unless your own code is part of a C implementation -- and if you have to ask, it isn't). There's no need to define such identifiers anyway; there's hardly any shortage of unreserved identifiers.

You can use an identifier like _foo as long as it's defined locally (not at file scope) -- but personally I find it much easier just to avoid using leading underscores at all.

Incidentally, your example of _sqrt doesn't necessarily illustrate the point. An implementation may define the name _sqrt in <math.h> (since anything defined there is at file scope), but there's no particular reason to expect that it will do so. When I compile your program, I get a warning:

c.c:7:1: warning: implicit declaration of function ‘_sqrt’ [-Wimplicit-function-declaration]

because <math.h> on my system doesn't define that identifier, and a link-time fatal error:

/tmp/cc1ixRmL.o: In function `main':
c.c:(.text+0x1a): undefined reference to `_sqrt'

because there's no such symbol in the library.

what is the use of (Underscore) in C?

It's just an identifier, it's valid. You can use _ by itself as an identifier.

For example you can do this

int _;

that makes _ a variable of type int.

The code though, exposes a fundamental problem because it calls main() from within the program. Doing so, invokes undefined behavior.



Related Topics



Leave a reply



Submit