Pragma Directives
Master #pragma directives for compiler-specific control: packing structures, optimization hints, warnings, deprecated functions, and platform-specific features. Learn standard and compiler-specific pragmas.
What are Pragmas?
#pragma provides compiler-specific directives. Unlike standard C features, pragmas vary by compiler. Unknown pragmas are ignored, so code remains portable. Use pragmas for optimization, warnings, structure packing, and platform features. Always provide non-pragma alternatives when possible.
#include <stdio.h>
/* Basic pragma syntax */
#pragma directive_name
/* Compiler-specific pragmas */
/* GCC/Clang */
#pragma GCC diagnostic ignored "-Wunused-variable"
/* MSVC */
#pragma warning(disable: 4996)
/* Standard pragmas (C99+) */
#pragma STDC FP_CONTRACT ON
#pragma STDC FENV_ACCESS ON
#pragma STDC CX_LIMITED_RANGE ON
/* _Pragma operator (C99) - can be used in macros */
_Pragma("pack(1)")
/* Equivalent to */
#pragma pack(1)
/* Using _Pragma in macros */
#define DISABLE_WARNING(text) _Pragma(#text)
DISABLE_WARNING(GCC diagnostic ignored "-Wunused")
/* Pragma sections */
#pragma section_start
/* Code here */
#pragma section_end
/* Unknown pragmas ignored (portability) */
#pragma some_unknown_feature
/* No error, just ignored */
/* Common pragma uses:
- Structure packing
- Warning control
- Optimization hints
- Code sections
- Function attributes
- Deprecated warnings
- Platform features
*/Structure Packing
Compilers add padding between struct members for alignment. #pragma pack controls this. Packed structures save space but may cause slower access or alignment issues. Essential for binary file formats, network protocols, and interfacing with hardware.
#include <stdio.h>
/* Normal structure (with padding) */
struct Normal {
char c; /* 1 byte */
/* 3 bytes padding */
int i; /* 4 bytes */
char c2; /* 1 byte */
/* 3 bytes padding */
}; /* Total: 12 bytes */
/* Packed structure (no padding) */
#pragma pack(push, 1)
struct Packed {
char c; /* 1 byte */
int i; /* 4 bytes */
char c2; /* 1 byte */
}; /* Total: 6 bytes */
#pragma pack(pop)
void packing_example(void) {
printf("Normal: %zu bytes\n", sizeof(struct Normal)); /* 12 */
printf("Packed: %zu bytes\n", sizeof(struct Packed)); /* 6 */
}
/* Different pack values */
/* 1-byte alignment (tightest) */
#pragma pack(1)
struct Pack1 {
char c;
int i;
}; /* 5 bytes */
#pragma pack()
/* 2-byte alignment */
#pragma pack(2)
struct Pack2 {
char c;
int i;
}; /* 6 bytes */
#pragma pack()
/* 4-byte alignment (default on many systems) */
#pragma pack(4)
struct Pack4 {
char c;
int i;
}; /* 8 bytes */
#pragma pack()
/* Push/pop pattern (save/restore) */
#pragma pack(push) /* Save current */
#pragma pack(1) /* Set to 1 */
struct MyStruct {
/* ... */
};
#pragma pack(pop) /* Restore previous */
/* Named push/pop */
#pragma pack(push, tight_pack)
#pragma pack(1)
/* ... structures ... */
#pragma pack(pop, tight_pack)
/* Platform-specific packing */
/* GCC/Clang attribute */
struct __attribute__((packed)) PackedGCC {
char c;
int i;
}; /* 5 bytes */
/* MSVC */
#pragma pack(push, 1)
struct PackedMSVC {
char c;
int i;
};
#pragma pack(pop)
/* Portable packed structure */
#if defined(__GNUC__)
#define PACKED __attribute__((packed))
#elif defined(_MSC_VER)
#define PACKED
#pragma pack(push, 1)
#else
#define PACKED
#endif
struct PACKED PortableStruct {
char c;
int i;
};
#ifdef _MSC_VER
#pragma pack(pop)
#endif
/* Binary file format example */
#pragma pack(push, 1)
struct FileHeader {
uint32_t magic; /* Magic number */
uint16_t version; /* File version */
uint32_t size; /* Data size */
uint16_t flags; /* Flags */
};
#pragma pack(pop)
/* Networking protocol */
#pragma pack(push, 1)
struct PacketHeader {
uint8_t type;
uint16_t length;
uint32_t sequence;
uint8_t checksum;
};
#pragma pack(pop)
/* Performance considerations */
void alignment_performance(void) {
/* Aligned access (fast) */
struct Aligned {
int x;
} __attribute__((aligned(4)));
/* Packed access (slower on some architectures) */
#pragma pack(push, 1)
struct PackedSlow {
char padding;
int x; /* Misaligned! */
};
#pragma pack(pop)
}
/* When to use packing */
/*
Use #pragma pack when:
- Reading/writing binary files
- Network protocols
- Hardware registers
- Interfacing with other languages
Don't use when:
- Performance critical
- Only internal structures
- Not required by spec
*/Warning Control
Pragmas control compiler warnings: disable specific warnings, treat warnings as errors, push/pop warning state. Use carefully - suppressed warnings may hide bugs. Document why warnings are disabled. Prefer fixing code over suppressing warnings.
/* GCC/Clang warning control */
/* Disable specific warning */
#pragma GCC diagnostic ignored "-Wunused-variable"
int unused_var; /* No warning */
/* Push/pop warning state */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
void function(int unused) { /* No warning */
/* ... */
}
#pragma GCC diagnostic pop
/* Now warnings restored */
/* Multiple warnings */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wformat"
/* Code with suppressed warnings */
#pragma GCC diagnostic pop
/* Treat warning as error */
#pragma GCC diagnostic error "-Wformat"
/* Invalid format causes compile error */
// printf("%d", "string"); /* Error! */
/* MSVC warning control */
/* Disable warning */
#pragma warning(disable: 4996) /* Deprecated function */
/* Enable warning */
#pragma warning(default: 4996)
/* Treat as error */
#pragma warning(error: 4996)
/* Push/pop */
#pragma warning(push)
#pragma warning(disable: 4996)
/* Code */
#pragma warning(pop)
/* Multiple warnings */
#pragma warning(disable: 4244 4267 4305)
/* Portable warning suppression */
#if defined(__GNUC__)
#define SUPPRESS_WARNING_PUSH \
_Pragma("GCC diagnostic push")
#define SUPPRESS_WARNING(w) \
_Pragma(#w)
#define SUPPRESS_WARNING_POP \
_Pragma("GCC diagnostic pop")
#elif defined(_MSC_VER)
#define SUPPRESS_WARNING_PUSH \
__pragma(warning(push))
#define SUPPRESS_WARNING(w) \
__pragma(warning(disable: w))
#define SUPPRESS_WARNING_POP \
__pragma(warning(pop))
#else
#define SUPPRESS_WARNING_PUSH
#define SUPPRESS_WARNING(w)
#define SUPPRESS_WARNING_POP
#endif
/* Usage */
SUPPRESS_WARNING_PUSH
SUPPRESS_WARNING(-Wunused-variable)
int unused;
SUPPRESS_WARNING_POP
/* Common warnings to control */
/* Unused variable */
#pragma GCC diagnostic ignored "-Wunused-variable"
/* Unused parameter */
#pragma GCC diagnostic ignored "-Wunused-parameter"
/* Format string */
#pragma GCC diagnostic ignored "-Wformat"
/* Sign comparison */
#pragma GCC diagnostic ignored "-Wsign-compare"
/* Type limits */
#pragma GCC diagnostic ignored "-Wtype-limits"
/* Deprecated */
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
/* Example: Suppressing in specific code */
void legacy_api(int param) {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
old_function(); /* Deprecated but needed */
#pragma GCC diagnostic pop
}
/* Document why warnings suppressed */
/* Suppress false positive from static analyzer */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
int value; /* Actually initialized below */
if (condition) {
value = 10;
} else {
value = 20;
}
#pragma GCC diagnostic pop
/* Better: Fix code instead */
int value = condition ? 10 : 20; /* No warning */Optimization and Function Attributes
Pragmas provide optimization hints: inline expansion, loop unrolling, function attributes. Help compiler generate better code. Non-portable but powerful for performance-critical sections.
/* GCC function attributes via pragma */
/* Optimize function */
#pragma GCC optimize("O3")
void fast_function(void) {
/* Compiled with O3 regardless of global setting */
}
/* Disable optimization */
#pragma GCC optimize("O0")
void debug_function(void) {
/* Not optimized - easier debugging */
}
/* Target-specific optimization */
#pragma GCC target("avx2")
void simd_function(void) {
/* Can use AVX2 instructions */
}
/* MSVC optimization */
#pragma optimize("", off)
void no_optimize(void) {
/* Optimization off */
}
#pragma optimize("", on)
/* Inlining hints */
#pragma GCC push_options
#pragma GCC optimize("inline-functions")
void inline_candidate(void) {
/* More likely to be inlined */
}
#pragma GCC pop_options
/* Loop unrolling */
void loop_function(void) {
#pragma GCC unroll 4
for (int i = 0; i < 16; i++) {
/* Loop unrolled 4x */
}
#pragma GCC unroll 8
for (int i = 0; i < 64; i++) {
/* Loop unrolled 8x */
}
}
/* Vectorization hints */
void vector_function(void) {
int a[1000], b[1000], c[1000];
#pragma GCC ivdep /* Ignore dependencies */
for (int i = 0; i < 1000; i++) {
a[i] = b[i] + c[i];
}
}
/* OpenMP pragmas (if supported) */
void parallel_function(void) {
#pragma omp parallel for
for (int i = 0; i < 1000; i++) {
/* Parallelized loop */
}
}
/* MSVC code sections */
#pragma code_seg(".text")
void normal_function(void) {
/* In .text section */
}
#pragma code_seg(".hotpath")
void hot_function(void) {
/* In custom section */
}
#pragma code_seg()
/* Function alignment */
#pragma GCC push_options
#pragma GCC optimize("align-functions=32")
void aligned_function(void) {
/* 32-byte aligned for cache */
}
#pragma GCC pop_options
/* Compiler barriers */
void barrier_example(void) {
int x = 0;
#pragma GCC memory_order_seq_cst
x = 1; /* Memory fence */
}
/* CPU detection */
#ifdef __AVX2__
#pragma GCC target("avx2")
void avx2_optimized(void) {
/* AVX2 code */
}
#else
void avx2_optimized(void) {
/* Fallback */
}
#endif
/* Profile-guided optimization */
#pragma GCC pgo("hot")
void frequently_called(void) {
/* Marked as hot path */
}
#pragma GCC pgo("cold")
void rarely_called(void) {
/* Marked as cold path */
}Deprecation and Compatibility
Mark functions, types, or macros as deprecated. Warns users to migrate to newer APIs. Provides transition period. Essential for library maintenance and API evolution.
/* GCC deprecation */
__attribute__((deprecated))
void old_function(void);
__attribute__((deprecated("Use new_function instead")))
void old_function2(void);
/* MSVC deprecation */
__declspec(deprecated)
void old_function3(void);
__declspec(deprecated("Use new_function instead"))
void old_function4(void);
/* Portable deprecation macro */
#if defined(__GNUC__)
#define DEPRECATED(msg) __attribute__((deprecated(msg)))
#elif defined(_MSC_VER)
#define DEPRECATED(msg) __declspec(deprecated(msg))
#else
#define DEPRECATED(msg)
#endif
DEPRECATED("Use new_api instead")
void legacy_api(void);
/* Using deprecated functions triggers warnings */
void caller(void) {
legacy_api(); /* Warning: deprecated */
}
/* Deprecating types */
typedef struct DEPRECATED("Use NewStruct") OldStruct {
int data;
} OldStruct;
/* Deprecating macros */
#define OLD_MACRO 1 DEPRECATED("Use NEW_MACRO")
#define NEW_MACRO 2
/* Conditional deprecation */
#if API_VERSION >= 2
DEPRECATED("Removed in version 3")
void transitional_function(void);
#endif
/* Suppress deprecation warnings */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
void using_deprecated(void) {
legacy_api(); /* No warning */
}
#pragma GCC diagnostic pop
/* Version-based deprecation */
#if defined(__GNUC__) && (__GNUC__ >= 5)
#define DEPRECATED_SINCE(ver, msg) \
__attribute__((deprecated(msg " (deprecated since " #ver ")")))
#else
#define DEPRECATED_SINCE(ver, msg)
#endif
DEPRECATED_SINCE(2.0, "Use new_function")
void old_function_v2(void);
/* Gradual migration */
/* Version 1.0 */
void api_function(void); /* Current */
/* Version 2.0 */
DEPRECATED("Use api_function_v2")
void api_function(void); /* Deprecated */
void api_function_v2(void); /* New */
/* Version 3.0 */
/* api_function removed */
void api_function_v2(void); /* Current */
/* Compatibility layers */
#ifndef NO_DEPRECATED_API
/* Old API still available */
DEPRECATED("Use new API")
void old_api(void);
#endif
/* Migration helpers */
#define USE_OLD_API 0
#if USE_OLD_API
#define API_CALL old_function
#else
#define API_CALL new_function
#endif
void code(void) {
API_CALL(); /* Flexible */
}Platform-Specific Pragmas
Each compiler/platform has unique pragmas. Understanding platform-specific pragmas helps with optimization, debugging, and system integration. Always provide fallbacks for portability.
/* GCC/Clang specific */
/* Visibility control */
#pragma GCC visibility push(hidden)
void internal_function(void); /* Hidden */
#pragma GCC visibility pop
/* Weak symbols */
__attribute__((weak))
void overridable_function(void) {
/* Default implementation */
}
/* Poison identifiers */
#pragma GCC poison malloc /* Error if malloc used */
/* System header */
#pragma GCC system_header /* Treat as system header */
/* MSVC specific */
/* Instruction set */
#pragma intrinsic(_ReadBarrier)
#pragma intrinsic(_WriteBarrier)
/* DLL export/import */
#pragma comment(lib, "user32.lib")
/* Data sections */
#pragma data_seg(".mydata")
int shared_data = 0;
#pragma data_seg()
/* Init sections */
#pragma init_seg(compiler)
#pragma init_seg(lib)
#pragma init_seg(user)
/* Intel compiler */
/* Vectorization */
#pragma ivdep
#pragma vector always
#pragma simd
/* HP-UX */
#pragma HP_INLINE
/* IBM XL */
#pragma isolated_call
/* Portable wrapper example */
#if defined(__GNUC__)
#define WEAK __attribute__((weak))
#define EXPORT __attribute__((visibility("default")))
#elif defined(_MSC_VER)
#define WEAK
#define EXPORT __declspec(dllexport)
#else
#define WEAK
#define EXPORT
#endif
WEAK void plugin_init(void) {
/* Can be overridden */
}
EXPORT void public_api(void) {
/* Exported */
}
/* Conditional pragma usage */
#if defined(__GNUC__) && !defined(__clang__)
/* GCC-only pragma */
#pragma GCC optimize("tree-vectorize")
#endif
#ifdef _MSC_VER
/* MSVC-only */
#pragma warning(disable: 4100)
#endif
/* Feature detection */
#ifdef __has_attribute
#if __has_attribute(warn_unused_result)
#define MUST_USE __attribute__((warn_unused_result))
#else
#define MUST_USE
#endif
#else
#define MUST_USE
#endif
MUST_USE int important_function(void);
/* Pragma in macros */
#define OPTIMIZE_FUNC \
_Pragma("GCC optimize(\"O3\")")
OPTIMIZE_FUNC
void fast_func(void) {
/* ... */
}Summary & What's Next
Key Takeaways:
- ✅ #pragma provides compiler-specific directives
- ✅ Unknown pragmas are ignored (portability)
- ✅ #pragma pack controls structure alignment
- ✅ Warning control with push/pop
- ✅ Optimization hints for performance
- ✅ Deprecation warnings for API migration
- ✅ Platform-specific features available
- ✅ Always provide portable fallbacks