# #pragma once In C and C++ programming languages `#pragma once` is a non-standard preprocessor directive that is equivalent to [[header-guard|header guards]]. You just put `#pragma once` at the top, rather than wrapping the entire header within header guards. Header guards: ```cpp // image.h #ifndef __IMAGE_H__ #define __IMAGE_H__ struct Image { ... }; #endif /* __IMAGE_H__ */ ``` Pragma once: ```cpp // 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: ```c #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|GCC]] compiler -- you can use `#pragma GCC poison` in order to ban (or "poison") certain identifiers. It's [well-known](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used) 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](https://gcc.gnu.org/onlinedocs/cpp/Pragmas.html). ```c /* 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 #pragma GCC poison gets int main() { char str[BUFSIZ]; gets(str); puts(str); return 0; } ``` ### OpenMP example A multithreading library [[openmp|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. ```c /* Compile: gcc -fopenmp main.c -o omp_two_threads Run: ./omp_two_threads Result: aaaaaaabbbbbbbaaaaaaabbbbb Stop: Ctrl + C */ #include #include #include #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; } ``` ## Links - https://gcc.gnu.org/onlinedocs/cpp/Pragmas.html - https://en.wikipedia.org/wiki/Pragma_once