There are two useful #pragma directives I like to use in my code: one let’s the preprocessor know that you want to include a header fine only once, and another deals with structure packing.
Instead of using the header include guards, which are ugly as sin, use #pragma once at the beginning of your header files, like this:
1 2 3 |
// This is a header file... #pragma once // now it will be included only once ... |
For structure packing, use #pragma pack directive. It tells the compiler about the default field alignment. On Clang 8.0.0 the sizeof of this structure is 32 bytes:
1 2 3 4 5 6 7 8 9 |
struct S1 { char c; short s; int i; long l; float f; double d; }; |
We can pack it down to 27 bytes by using this directive (it tells the compiler to align all member fields on one byte boundary; this is useful when designing efficient network protocols or data serialization):
1 2 3 4 5 6 7 8 9 10 11 |
#pragma pack(1) struct S2 { char c; short s; int i; long l; float f; double d; }; |
You can also show, at compile time, what the current packing alignment is with #pragma pack(show). Current alignment can be pushed onto a stack, then reverted back, with #pragma pack(push, 1) followed by #pragma pack(pop).
Complete listing (pragma.cpp):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
#include <iostream> using namespace std; struct S1 { char c; short s; int i; long l; float f; double d; }; #pragma pack(show) #pragma pack(push, 1) #pragma pack(show) struct S2 { char c; short s; int i; long l; float f; double d; }; #pragma pack(pop) int main() { cout << sizeof(S1) << ", " << sizeof(S2) << endl; } |
32, 27
Program output.
Note that none of the pragmas are specified by the ISO standard.
The
#pragma once
is a de facto standard, AFAIK supported by all modern C++ compilers, except Cray C++ (don’t know how modern that implementation is). Wikipedia provides a list of compiler support.
#pragma pack
is also a de facto standard very much worth knowing about, but possibly not as universal as
#pragma once
. There may be differences between compilers about arguments etc. A good reason to use it is to get complete control over the memory layout. A bad reason to use it is to just save space (that’s better done by using the relevant optimization option in the compiler invocation).
#pragma once has also its drawbacks as this article points out
https://hackernoon.com/generated-include-guards-an-alternative-to-pragma-once-31cc3dee6ce