Table of Contents
#pragma once
In C and C++ programming languages #pragma once is a non-standard preprocessor directive that is equivalent to header guards.
You just put #pragma once at the top, rather than wrapping the entire header within header guards.
Header guards:
// image.h #ifndef __IMAGE_H__ #define __IMAGE_H__ struct Image { ... }; #endif /* __IMAGE_H__ */
Pragma once:
// image.h #pragma once struct Image { ... };
Should I use #pragma once?
It's up to you! It's widely supported by almost all C and C++ compilers – even though it's not technically defined by the standard in either programming language.
An advantage is that there is less chance you will make a typo like this:
#ifndef __HEADER_H_ #define __HEADER_H__ /* ... */ #endif
There is no good reason not to use #pragma once although my preferences still rather lean towards header guards simply because I feel most C and C++ programmers will find them more familiar.
What is #pragma?
#pragma is a preprocessor directive that instructs the compiler to employ some non-standard behavior – beyond the language itself. #pragma directive itself is part of the C standard, but what exactly #pragma does is up to the compilers.
GCC example
As an example – if you use the GCC compiler – you can use #pragma GCC poison in order to ban (or “poison”) certain identifiers. It's well-known among C programmers that gets() is a dangerous function that should not be used. So you use #pragma GCC poison gets to ban it altogether!
Well, maybe gets() is a bad example because GCC already bans it and tells you to use fgets(). ;)
You can read more about GCC #pragma directive here.
/* Compile: gcc main.c Error: main.c: In function ‘main’: main.c:24:5: error: attempt to use poisoned ‘gets’ 24 | gets(str); | ^ main.c:19:20: note: poisoned here 19 | #pragma GCC poison gets | ^~~~ main.c:24:5: error: implicit declaration of function ‘gets’; did you mean ‘fgets’? [-Wimplicit-function-declaration] 24 | gets(str); | ^~~~ | fgets */ #include <stdio.h> #pragma GCC poison gets int main() { char str[BUFSIZ]; gets(str); puts(str); return 0; }
OpenMP example
A multithreading library OpenMP uses #pragma extensively directive extensively!
All OpenMP directives start with #pragma omp.
The following example creates two competing threads – one that prints a red letter 'a', the other that prints a green letter 'b'. You cancel the program with a SIGINT signal by pressing Ctrl + C.
You have to remember to compile the source code with -fopenmp option.
/* Compile: gcc -fopenmp main.c -o omp_two_threads Run: ./omp_two_threads Result: aaaaaaabbbbbbbaaaaaaabbbbb Stop: Ctrl + C */ #include <stdio.h> #include <unistd.h> #include <omp.h> #define RED "\e[31m" #define GREEN "\e[32m" #define NONE "\e[0m" #define A_STR RED "a" NONE #define B_STR GREEN "b" NONE int main() { #pragma omp parallel num_threads(2) { int tid = omp_get_thread_num(); for ( ; ; ) { #pragma omp crticial { printf("%s", tid == 0 ? A_STR : B_STR); } } } return 0; }
