use _ and __ in C programs [duplicate]
Asked Answered
M

3

21

I was reading K&R book. I read:

...name intended for use only by functions of the standard library begin with _ so they are less likely to collide with the names in the user program...

What does this exactly means please explain real simple and practical way.

What i understood is:

if i want to use sqrt defined in math.h then

#include <math.h>
#define sqrt(x) x*x*x

main() 
{ 
int x=4; 
_sqrt(x); // That is from the header file math.h
sqrt(x); // my own defined macro 
/*or its the reverse way _sqrt for my own defined macro so it won't collide with original sqrt i.e. without _ for sqrt from math.h */ 
return 0;
}

Now, I read a code on stackoverflow using __. sys/syscall.h is not present in windows so we have to use

#if __linux 
#include <sys/syscall.h>
#elif defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#endif

Where exactly is __ used and what's the difference b/w __ & _.

Madra answered 2/8, 2014 at 1:1 Comment(5)
I believe some of them are reserved for the compiler tooContactor
"explain real simple and practical way." - Don't begin the names of your things with _ or __.Sivas
Exactly what @meagar said. Unless you're writing your own compiler or libc, or really want to play language-lawyer, just don't name anything with a leading underscore and you'll be fine.Drawtube
There are many possible duplicates, including: Meaning of notations like _NAME, _NAME_, __NAME, __NAME__ and Commonly accepted variable name formatting in C/C++ and Understanding glibc source conventions and even What does __const mean in C etc.Overact
You're defining sqrt to mean cubed? Why?Invest
P
31

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.

Pathogenesis answered 2/8, 2014 at 1:15 Comment(3)
Does this advice (to not use leading _ followed by lower-case alpha character at file scope) apply to static functions, i.e. with internal linkage? I suppose since they have file scope, it does. Is there a popular naming convention for static functions that can be used (and thus commonly recognised) instead? I prefix my public function names with the module name (e.g. foo_sqrt()), so I suppose at the least my static functions could just not have the foo_ prefix.Bowser
Yes, file-scope static functions are still file-scope, so names starting with _ are still preserved in that context. Really, the easiest thing to do is just never declare something with a name starting with _ (unless you're writing part of the implementation). Don't use the name sqrt, since <math.h> might define it as a macro. More generally, I wouldn't re-use any name defined by the standard library, simply to avoid confusion even if it's in a safe context. (For example, don't call a logging function log, since that's the name of the natural logarithm function.)Pathogenesis
To remind: the user can write macros that begin with an underscore, followed by a lowercase letter.Gee
H
12

It's a naming convention, this means that violating this rule will not immediately and directly lead to breaking your program, but it's a really really really really really really [ + infinite times ] a good idea to follow the convention.

The essence of the convention is to reserve :

  • naming starting with _ for the language entities, which includes the standard library
  • naming starting with __ for the compiler internals

it's also a really platform specific topic most of the times, many vendors respect this convention but they also have their own naming conventions and guidelines .

You can find more by search for c double underscore naming convention

Haul answered 2/8, 2014 at 1:13 Comment(5)
"Language entities" versus "compiler internals" is not a correct description of the distinction.Drawtube
@R.. Comments like this one are the reason why the world is so beautiful; If you have something to say, just say it, you a programmer, you function, just go for it.Haul
I'm not quite sure what to make of your reply. Other answers have cited the text in the standard on what the formal distinction between _ and __ really is. Your answer is largely right, but I don't see any evidence backing up your claim about how they're used for "language entities" versus "compiler internals".Drawtube
An implementation of the standard library is free to define identifiers starting with __.Pathogenesis
Standard library implementor cannot freely use names starting with _ but not followed by another underscore nor a capital letter. These names serve as internal identifiers for user code. Any C implementation with static int _foo; in one of its system header is broken; it breaks conforming user code to do so.Ottar
M
-1

tl; dr You got it backwards. Name your own stuff without leading underscores, unless you're writing a library for someone else. The standard library and compilers use the technique to signal that certain names are internal, and not to be used directly.

Underscores for Uniqueness

In C, there are no namespaces. In other words, all names included into a file can collide with each other. If foo.h and bar.h both define x, an error will occur when they are both included.

Now, x is a pretty common name. Collision is almost guaranteed, and the writers of foo.h and bar.h must realize that. So, in the interest of avoiding future problems for the programmers that will use their code, they change the name to _x.

Alternatives

Common names do occur. Before resorting to underscoring, try:

  1. Separating private from public variables in .c and .h files. Most clashing names are private, and don't belong in the header.

  2. Prefixing your code with the name of the module: foo_x and bar_x won't collide.

Md answered 2/8, 2014 at 1:13 Comment(5)
Libraries that are not part of the C implementation still shouldn't define identifiers with leading underscores.Pathogenesis
There are namespaces in C, just not the same ones that are in C++ or other languages. struct foo; and typedef int foo; don't collide in C due to the tag namespace, but they do collide in C++.Greenburg
Does this advice (to not use leading _) apply to static functions?Bowser
Haven't coded C for over 5 years now, so I'm a little out of fashion, but the logic is the same: underscore stuff to signal that it shouldn't be used outside of library boundaries, and to avoid clashing with the caller's own namespaces. What the current standards are, no idea, but the reasoning holds.Md
"unless you're writing a library for someone else" should read "unless you're writing the Standard Library".Uniliteral

© 2022 - 2024 — McMap. All rights reserved.