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;
}