Alan
Alan

Reputation: 101

Understanding different styles of #defines in c

I was looking at different source codes in C programming language and found different styles of #define's used.

I know technically their use case and irrespective of their style they will work as expected but from coding guidelines, I would like to ask what do they mean and when to use a particular one.

#define MY_DEFINE_H

#define MY_DEFINE_H_

#define MY_DEFINE_H__

#define __MY_DEFINE_H__

Also if possible please share some reference so that I can go through detailed in it.

Upvotes: 4

Views: 169

Answers (1)

Jonathan Leffler
Jonathan Leffler

Reputation: 754920

Note that you should not, in general, create function, variable, tag or macro names that start with an underscore. Part of C11 §7.1.3 Reserved identifiers says:

  • 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.

See also What does double underscore (__const) mean in C?

That means the last name (__MY_HEADER_H__) can be used by 'system' headers (and the others can't be used by system headers). Note that a common problem is that new programmers look to see what the system headers do and copy them, not realizing that the rules for the headers provided by 'the implementation' (what I called system headers) are subject to different rules from headers written by users. Consequently, people inadvertantly trample on the system namespace thinking it is a good idea because that's what the system headers do, not realizing that they must not do it so that the system headers can be written safely.

Technically, you can use any of the other three names yourself. I don't like the trailing underscores so I don't use them in the absence of a compelling reason. Are these header guards to prevent multiple inclusions?

#ifndef MY_HEADER_H
#define MY_HEADER_H
…
#endif /* MY_HEADER_H */

If the names are for header guards, using a single or double underscore means they're less likely to collide with other names. You're not likely to refer to these macros. You should resist the temptation to try writing in some other source file:

#ifndef MY_HEADER_H__
#include "my_header.h"
#endif

The name in the header could change. It is crucial that the header contains a set of header guards (the exceptions are rare). But code outside the header itself should not usually be aware of that name.

I tend to use either HEADER_H or HEADER_H_INCLUDED for file header.h (and I seldom if ever use 'my' as a prefix to anything), but the name doesn't matter as long as it is unique (an MD5 checksum for the file is likely to be fine — this isn't a security application).

Upvotes: 9

Related Questions