8

Possible Duplicate:
#pragma once vs include guards?

When should I use #pragma once?

When should I use #ifndef HEADER_H_INCLUDED?

Community
  • 1
  • 1
machchakumar
  • 195
  • 5
  • 9

4 Answers4

12

The #ifndef/#define/#endif trick works on any C compiler, and on some of them it speeds up the compilation process. The #pragma trick is non-standards, and only works on few C compilers, and may result in different semantics in those that do not support it.

  • 2
    Note though, that it's supported on the big three: GCC, MSVC, and ICC. – Billy ONeal Jul 11 '10 at 05:59
  • 3
    Even if it were supported by all but one, it would still be stupid to use it since there's a trivial method (the `#ifndef` one) which works on all compilers and is universally familiar to anyone who knows C. – R.. GitHub STOP HELPING ICE Jul 11 '10 at 06:01
  • 1
    @R: Unless you (and maybe your team, whom is all using the same compiler) is the only one on the project. I've had problems in the past where I'd rename a header file but forget to update the `#ifndef`. Or if that particular constant accidentally gets copied. – mpen Jul 11 '10 at 06:35
  • 1
    @Mark: feel free to use a UUID or just some random string followed by the exact date and time the header was originally created instead of the filename in the `#ifndef`. There's no excuse for `#pragma once`. – R.. GitHub STOP HELPING ICE Jul 11 '10 at 06:57
  • Even if you your team's current compilers support a non-standard extension, will your future ones do? That's the risky bit about non-standard stuff. –  Jul 11 '10 at 20:54
5

The difference is that the latter is C and the former is not. Never use #pragma once; always use #ifndef.

One other thing to note when using the #ifndef method is that any preprocessor symbol beginning with two underscores or an underscore followed by a capital letter is reserved and cannot be used. You should use things like #ifndef MYHEADER_H and not #ifndef _MYHEADER_H.

R.. GitHub STOP HELPING ICE
  • 195,354
  • 31
  • 331
  • 669
  • 1
    Strictly, `#pragma` is C; there are even some standard pragmas. You would be correct if you said "Don't use `#pragma once`", though. – Jonathan Leffler Jul 11 '10 at 06:06
  • But `#pragma once` is not C. It's an implementation-defined use of `#pragma`. – R.. GitHub STOP HELPING ICE Jul 11 '10 at 06:12
  • The point I'm making is that your statement 'Never use `#pragma`' is an over-statement; there are legitimate and C99 standard uses for Standard C pragmas - specifically,`#pragma STDC FP_CONTRACT ON` is a perfectly standard and valid use of `#pragma`. However, as I said previously, stating that `#pragma once` is not standard and is best not used would be correct. – Jonathan Leffler Jul 11 '10 at 06:18
  • I meant to say "Never use `#pragma once`". I've fixed it now. – R.. GitHub STOP HELPING ICE Jul 11 '10 at 06:27
1

The construct

myfoo.h

#ifndef MYFOO_H
#define MYFOO_H

/* header information for myfoo.h */

#endif

belongs in every header-file. The trick is: you can include a header file (accidentally) more than once without thinking abaout double declarations. so this is for the preprocessor.

The #pragma is for the compiler, and a preprocessor should ignore pragmas it does not understand.

Jonathan Leffler
  • 666,971
  • 126
  • 813
  • 1,185
Peter Miehle
  • 5,777
  • 2
  • 35
  • 53
  • 3
    I wouldn't call it 'accidentally'. It's more likely that header files B and C both depend on header file A and thus both include it. Then, if one source file includes both header files B and C, it will thereby include header file A twice. – R.. GitHub STOP HELPING ICE Jul 11 '10 at 06:02
1

Use #pragma when you are addressing a specific compiler (or set of compatible compilers) to guide its code generation or if you are using a standardized #pragma like FP_CONTRACT or -CX_LIMITED_RANGE- that any standards-compliant compiler is going to support.

Use #ifndef and ilk if you are addressing the standard C (or C++) pre-processor and wish to have your code rendered portable across all standards-compliant compilers.

Use of any #pragma that is not defined in the C (or C++) standard renders your code non-portable. #pragma once is a bit of an exception in that it is one of the most commonly-implemented of the non-standard #pragma constructs. Its implementation, however, is not universal across standards-compliant compilers. #ifndef is.

JUST MY correct OPINION
  • 33,835
  • 16
  • 75
  • 95