3

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.

Alan
  • 91
  • 6
  • 3
    Just personal preference or project convention, for the most part. Macro names which both begin and end with an underscore (e.g. `_MY_DEFINE_H_`) are, I believe, reserved to the implementation, and theoretically should not be defined by user code, but for some reason doing so is very popular. (And I might be wrong that they're reserved.) – Steve Summit Aug 30 '19 at 15:45
  • It's a matter of personal preference. There is no special meaning for either of them – Jabberwocky Aug 30 '19 at 15:45
  • 1
    One reference is [question 1.29](http://c-faq.com/decl/namespace.html) in the old [C FAQ list](http://c-faq.com/), and it cites several other references. – Steve Summit Aug 30 '19 at 15:50
  • @SteveSummit: it is identifiers that begin with an underscore that are generally not for use by end users (programmers); they're reserved for use by 'the implementation'. Trailing underscores don't factor into the rules. See the quote and link to the standard in my [answer](https://stackoverflow.com/a/57730108/15168). – Jonathan Leffler Aug 30 '19 at 18:49

1 Answers1

8

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

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 1
    Good answer. I may add that colliding header guards can cause some confusion and can easily happen if code is organized as components in different folders. Hence I sometimes prefix the definition with the folder name as in: `#define FOLDER__HEADER_H`. An alternative to all this is of course `#pragma once`, but I cannot get myself to use it. – nielsen Aug 30 '19 at 16:57
  • 1
    @nielsen `#pragma once` is _more_ troublesome than header guards. If header guards collide, you can change one of the guard macro names without worrying about breaking anything else. If the compiler's idea of "these two #includes refer to the same file" for `#pragma once` purposes is wrong, your only options are to rename one of the headers or stop using `#pragma once`, both of which may be a major headache. – zwol Aug 30 '19 at 17:22
  • 1
    I have a script for generating header guards. It works with the pathname given; if you say `hdrguard somedirectory/someheader.h`, it will generate `#ifndef SOMEDIRECTORY_SOMEHEADER_H_INCLUDED` by default — it can be tweaked by options to generate all sorts of alternatives. The hex encoding of even a 32-bit random number (let alone 64-bit or bigger) is likely to be fairly good. I mentioned the MD5 checksum — the script can be told to use any hash command (`sha1`, `sha2-256`, `sha3-512`, …) that generates a hash on standard output from the data read from its standard input. – Jonathan Leffler Aug 30 '19 at 19:00
  • @zwol Your concern is of course valid. I do not want to repeat [discussions](https://stackoverflow.com/questions/787533/is-pragma-once-a-safe-include-guard) about `pragma once`. As said, I do not use it myself, but wanted to mention it because - like it or not - it _is_ an alternative to header guards. – nielsen Sep 02 '19 at 06:30