Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/MicrosoftDocs/cpp-docs/llms.txt

Use this file to discover all available pages before exploring further.

Pragma directives specify machine-specific or operating system-specific compiler features. A line that begins with #pragma passes an instruction directly to the compiler — after the preprocessor has expanded any macros in the token string. If the compiler does not recognize a pragma, it issues a warning and continues compilation, which makes pragmas safe to use even in code that may be compiled by multiple compilers (unrecognized pragmas are simply ignored). MSVC also supports two alternative pragma forms:
/* Standard #pragma — cannot be used inside a macro */
#pragma token-string

/* Microsoft __pragma — usable inside macro definitions */
__pragma(token-string)

/* Standard C99 _Pragma — usable inside macro definitions, standard portable form */
_Pragma("token-string")
The __pragma and _Pragma forms let you embed pragma directives inside macro definitions, which is impossible with #pragma because the # character would be interpreted as the stringizing operator.

#pragma once

#pragma once tells the compiler to include a header file only the first time it is encountered in a given translation unit. It is the modern, idiomatic alternative to the traditional #ifndef include guard.
/* header.h */
#pragma once

/* Everything below is included only once per translation unit */
typedef struct {
    int id;
    char name[64];
} User;

void user_print(const User *u);

Comparison with Include Guards

/* myheader.h */
#pragma once

#define MY_CONSTANT 42
void my_function(int x);
#pragma once reduces typing, avoids symbol-collision bugs between different headers accidentally using the same guard name, and can improve build performance because the compiler can skip the file entirely on subsequent #include directives without opening it. It is implemented portably in MSVC, GCC, and Clang.
Do not use #pragma once in header files intentionally designed to be included multiple times (for example, X-macro headers where inclusion has configurable side effects through other macros). Use the traditional include-guard idiom in those cases.

#pragma comment

#pragma comment inserts a record into the generated object file (.obj). The linker reads these records when combining object files, enabling you to embed linker instructions directly in source code.

Syntax

#pragma comment(comment-type [, "comment-string"])

Comment Types

The most commonly used comment type. It instructs the linker to search for the named library, just as if you had specified it on the command line with /link libname.lib.
/* Link against Windows networking library */
#pragma comment(lib, "ws2_32.lib")

/* Link against DirectX */
#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "dxgi.lib")

/* Link a custom library */
#pragma comment(lib, "my_engine.lib")
This technique lets you put library dependencies next to the code that uses them, so developers don’t need to separately configure project linker settings.
Places a linker option directly into the object file. Only a subset of linker options can be specified this way.
/* Force inclusion of a symbol (prevents linker dead-code stripping) */
#pragma comment(linker, "/include:__mySymbol")

/* Set a specific DLL export */
#pragma comment(linker, "/EXPORT:MyPublicFunction")

/* Specify a merge of sections */
#pragma comment(linker, "/MERGE:.rdata=.text")
Places the compiler name and version string into the object file (informational only; ignored by the linker):
#pragma comment(compiler)
Places a general text comment into the object file (ignored by the linker):
#pragma comment(user, "Compiled on " __DATE__ " at " __TIME__)
#pragma comment(user, "Author: Engineering Team, Build 2.5.1")

#pragma warning

#pragma warning enables fine-grained control over MSVC compiler warning messages. You can suppress, promote, or adjust the severity of individual warnings — or push and pop warning states to isolate changes to a specific code region.

Syntax

#pragma warning(specifier : warning-number-list)
#pragma warning(push [, level])
#pragma warning(pop)

Warning Specifiers

SpecifierEffect
disableSuppress the listed warning(s) entirely
errorTreat the listed warning(s) as errors
onceIssue the listed warning(s) at most one time
defaultRestore the listed warning(s) to their default level
suppressDisable the listed warning for the next single line, then restore
1, 2, 3, 4Set the listed warning(s) to the given severity level

Examples

/* Suppress a specific deprecation warning */
#pragma warning(disable : 4996)    /* 'strcpy': deprecated */
char *dst = strcpy(buf, src);
#pragma warning(default : 4996)    /* restore to default */

/* Treat warning 4100 (unreferenced parameter) as an error */
#pragma warning(error : 4100)

/* Suppress multiple warnings in one directive */
#pragma warning(disable : 4507 4034)

/* Issue warning 4385 only once across the translation unit */
#pragma warning(once : 4385)

Push and Pop — Scoped Warning State

The push/pop mechanism saves and restores the entire warning state, making it safe to change warnings for a block of code without affecting the rest of the file:
#pragma warning(push)               /* save current state */
#pragma warning(disable : 4244)     /* disable narrowing conversion warning */
#pragma warning(disable : 4100)     /* disable unreferenced parameter warning */

/* Third-party header that generates many warnings */
#include "noisy_third_party.h"

#pragma warning(pop)                /* restore all warnings to saved state */
/* Suppress a single-line warning */
#pragma warning(suppress : 4127)    /* conditional expression is constant */
while (true) {
    /* ... server loop ... */
}
Warning numbers in the range 4700–4999 are code-generation warnings. Changes to these warnings take effect at the end of the current function definition, not at the pragma’s location in the source. For these warnings, place the #pragma warning directive before the function definition.

#pragma optimize

#pragma optimize controls the optimization settings applied to individual functions. It must appear outside a function definition and takes effect at the first function defined after the pragma.

Syntax

#pragma optimize("optimization-list", { on | off })

Optimization Parameters

ParameterOptimization type
gGlobal optimizations (deprecated; use /Og)
sFavor short machine code sequences
tFavor fast machine code sequences
yOmit frame pointers on the program stack

Examples

/* Disable all optimizations for the next function (useful for debugging) */
#pragma optimize("", off)
int slow_debug_function(int x) {
    /* Compiler will not optimize this function */
    int tmp = x * 2;
    return tmp + x;
}
#pragma optimize("", on)   /* restore optimizations specified by /O switch */

/* Optimize for size (/Os equivalent) for a set of functions */
#pragma optimize("s", on)

void compact_function_a(void) { /* ... */ }
void compact_function_b(void) { /* ... */ }

#pragma optimize("", on)   /* restore global /O settings */

/* Omit frame pointers for a leaf function (faster prolog/epilog) */
#pragma optimize("y", on)
int leaf_math(int a, int b) {
    return a * b + a - b;
}
#pragma optimize("y", off)
#pragma optimize("", off) turns all optimizations off for the affected functions, regardless of the /O command-line setting. This is useful when a specific function is crashing or misbehaving in optimized builds and you need to debug it without changing the global build configuration.

#pragma pack

#pragma pack controls the alignment (packing) of structure, union, and class members. By default, the compiler aligns members on boundaries suited to the target architecture (typically the smaller of the member size and the default packing size of 8 bytes). Reducing packing can save memory at the cost of potential unaligned access performance penalties.

Syntax

#pragma pack(show)
#pragma pack([n])
#pragma pack(push [, identifier] [, n])
#pragma pack(pop  [, {identifier | n}])
Valid values for n: 1, 2, 4, 8, 16.

Example — Reducing Padding

#include <stddef.h>
#include <stdio.h>

/* Default packing */
struct DefaultLayout {
    char   a;   /* offset 0 */
    int    b;   /* offset 4 (3 bytes padding after 'a') */
    short  c;   /* offset 8 */
};              /* total size: 12 bytes */

/* Packed to 1-byte alignment */
#pragma pack(push, 1)
struct PackedLayout {
    char   a;   /* offset 0 */
    int    b;   /* offset 1 (no padding) */
    short  c;   /* offset 5 */
};              /* total size: 7 bytes */
#pragma pack(pop)

int main(void) {
    printf("Default: a=%zu b=%zu c=%zu  total=%zu\n",
           offsetof(struct DefaultLayout, a),
           offsetof(struct DefaultLayout, b),
           offsetof(struct DefaultLayout, c),
           sizeof(struct DefaultLayout));
    /* Output: Default: a=0 b=4 c=8  total=12 */

    printf("Packed:  a=%zu b=%zu c=%zu  total=%zu\n",
           offsetof(struct PackedLayout, a),
           offsetof(struct PackedLayout, b),
           offsetof(struct PackedLayout, c),
           sizeof(struct PackedLayout));
    /* Output: Packed:  a=0 b=1 c=5  total=7 */
    return 0;
}

Network Protocol Headers

#pragma pack is especially important when mapping C structures directly onto wire protocols or binary file formats:
/* Ethernet frame header — must match wire format exactly */
#pragma pack(push, 1)
typedef struct {
    unsigned char  dst_mac[6];
    unsigned char  src_mac[6];
    unsigned short ethertype;
} EthernetHeader;

typedef struct {
    unsigned char  version_ihl;
    unsigned char  dscp_ecn;
    unsigned short total_length;
    unsigned short identification;
    unsigned short flags_fragment;
    unsigned char  ttl;
    unsigned char  protocol;
    unsigned short checksum;
    unsigned int   src_ip;
    unsigned int   dst_ip;
} IPv4Header;
#pragma pack(pop)

/* Now sizeof(EthernetHeader) == 14, sizeof(IPv4Header) == 20 */
Accessing misaligned data can cause performance degradation on x86/x64 and a hardware exception on some ARM targets. Use #pragma pack only when binary layout correctness requires it, and wrap the pack/pop pair tightly around the affected declarations.

#pragma section

#pragma section creates a named section in the output object file (.obj). You then use __declspec(allocate("section-name")) to place specific variables into that section.

Syntax

#pragma section("section-name" [, attributes])
Available attributes: read, write, execute, shared, nopage, nocache, discard, remove.

Example

/* Create a read-only data section */
#pragma section("my_const", read)

__declspec(allocate("my_const"))
const int version_table[] = { 1, 2, 3, 4, 5 };

/* Create a shared section (shared across processes for the same DLL) */
#pragma section("shared_data", read, write, shared)

__declspec(allocate("shared_data"))
volatile int instance_count = 0;

/* Regular variable — goes into the default .data section, not my_const */
int normal_var = 99;
Once a section is defined with #pragma section, it remains valid for the rest of the compilation unit. However, a variable is only placed in that section if it carries the __declspec(allocate("section-name")) attribute.

#pragma intrinsic

#pragma intrinsic tells the compiler to treat calls to the listed functions as compiler intrinsics — inlining the function body with a few machine instructions rather than generating a real function call. Intrinsic forms exist for common library functions like memcpy, memset, strcmp, and mathematical functions.

Syntax

#pragma intrinsic(function_name [, function_name ...])

Example

#include <string.h>
#include <math.h>

/* Ask the compiler to use intrinsic forms of these functions */
#pragma intrinsic(memcpy, memset, memcmp, strlen, strcpy)
#pragma intrinsic(sqrt, abs, fabs)

void fast_copy(void *dst, const void *src, size_t n) {
    /* memcpy call may be replaced by optimized inline instructions */
    memcpy(dst, src, n);
}

double fast_hyp(double a, double b) {
    /* sqrt may be emitted as a single FSQRT / SQRTSD instruction */
    return sqrt(a * a + b * b);
}
Functions that support intrinsic forms include (among others): abs, fabs, memcmp, memcpy, memset, strcat, strcmp, strcpy, strlen, _rotl, _rotr, _lrotl, _lrotr. To revert to the normal library call, use #pragma function:
#pragma intrinsic(memcpy)
/* ... memcpy is intrinsic here ... */
#pragma function(memcpy)
/* ... memcpy is a real function call again ... */
The /Oi compiler option enables intrinsic forms globally for all supported functions. #pragma intrinsic gives you per-function control without enabling /Oi project-wide.

Using __pragma Inside Macros

Because #pragma cannot appear inside a macro definition (the # would be interpreted as the stringizing operator), MSVC provides __pragma as a keyword alternative and C99 provides _Pragma as a standard operator:
/* _Pragma — standard, portable */
#define DISABLE_WARNING_4127 \
    _Pragma("warning(suppress: 4127)")

/* __pragma — Microsoft-specific, also works */
#define BEGIN_SUPPRESS(n) \
    __pragma(warning(push)) \
    __pragma(warning(disable: n))

#define END_SUPPRESS() \
    __pragma(warning(pop))

/* Usage */
BEGIN_SUPPRESS(4100)   /* suppress unreferenced formal parameter */
void unused_param_func(int x) {
    printf("no x here\n");
}
END_SUPPRESS()

Complete Pragma Quick Reference

PragmaPurpose
#pragma oncePrevent multiple inclusion of a header
#pragma comment(lib, "name.lib")Auto-link a library
#pragma comment(linker, "option")Embed a linker option
#pragma warning(disable : N)Suppress warning N
#pragma warning(push/pop)Save and restore warning state
#pragma optimize("flags", on/off)Control per-function optimization
#pragma pack(n)Set struct member alignment
#pragma pack(push/pop)Save and restore alignment state
#pragma section("name", attrs)Create a named object file section
#pragma intrinsic(fn)Use intrinsic form of a function
#pragma function(fn)Revert to library call for a function
#pragma message("text")Print a message during compilation
#pragma hdrstopMark end of precompiled header includes
#pragma data_seg("name")Place initialized data in named section
#pragma bss_seg("name")Place uninitialized data in named section
#pragma code_seg("name")Place code in named section

See Also

Build docs developers (and LLMs) love