Fact-checked by Grok 2 weeks ago

sizeof

The sizeof operator is a compile-time unary operator in the C and C++ programming languages that returns the size, in bytes, of a given expression, variable, or type. It evaluates to an integer of type size_t, which represents the maximum size of any object, and is essential for determining memory requirements without executing runtime code. The operator can take either an expression (e.g., sizeof variable) or a parenthesized type name (e.g., sizeof(int)), and its result depends on the implementation's architecture, such as the size of fundamental types like char (always 1 byte) or int (typically 4 bytes on 32-bit systems). Introduced during the development of C in the early 1970s by Dennis Ritchie at Bell Labs, sizeof emerged as part of C's evolving type system, which was designed to support byte-addressable hardware like the PDP-11 computer used for Unix. Prior languages like B lacked strong typing, making explicit size queries unnecessary or impossible; C's addition of types such as char, int, and pointers necessitated a mechanism to query storage sizes for portability and efficient memory use. By 1978, the first edition of The C Programming Language by Kernighan and Ritchie formalized sizeof as a key feature for computing object sizes at compile time, enabling practices like array traversal (e.g., sizeof(array)/sizeof(array[0]) to find element count) and safe dynamic allocation via functions like malloc. In practice, sizeof promotes code portability by abstracting architecture-specific details, though results can vary (e.g., sizeof(long) may be 4 or 8 bytes). It cannot be applied to incomplete types, functions, or the void type, and for variable-length arrays (introduced in ), evaluation occurs at runtime. This operator remains foundational in , embedded development, and performance-critical applications, influencing standards like ISO (first published 1990) and C++ (first released in 1985).

Overview

Purpose

The [sizeof](/page/sizeof) operator is a unary compile-time operator in the C and C++ programming languages that yields the size, in bytes, of the object representation of a given type or the type of an expression, without evaluating the expression itself. This evaluation occurs at compile time, returning a value of type size_t, an unsigned integer type defined in <stddef.h>, which represents the storage size required for the operand. The operator originated in early implementations of C during the 1970s at Bell Labs and was formalized in the ANSI C standard (C89, also known as ISO/IEC 9899:1990), addressing inconsistencies in type sizes across diverse hardware platforms in pre-standard C compilers. Prior to standardization, variations in data type sizes between systems, such as different word lengths on mainframes versus minicomputers, complicated portability, and sizeof provided a to query these sizes explicitly within the . A primary purpose of sizeof is to enable portable by allowing developers to query and adapt to platform-specific type sizes, thereby avoiding hard-coded assumptions that could fail across architectures. It supports safe , such as in dynamic allocation with functions like malloc, where specifying the correct byte count—e.g., malloc(n * sizeof([int](/page/INT)))—ensures appropriate without excess or deficiency. By providing accurate sizes, it helps prevent common errors like buffer overflows in operations involving arrays or structures, where misjudging bounds could lead to memory corruption. For instance, sizeof([int](/page/INT)) is typically 4 bytes on both 32-bit and 64-bit systems, though the exact size is implementation-defined, highlighting the need for runtime-agnostic size determination to maintain reliability.

Syntax

The operator is a operator in C and C++ that yields the size in bytes of the object representation of its operand's type. It supports two primary syntactic forms: sizeof (type-name) to query the size of a specified type, and sizeof unary-expression to query the size of the type of the given expression. Parentheses are mandatory around a type name but optional around a unary expression, allowing forms such as sizeof x or sizeof(x) for expressions. The result is always a constant expression evaluated at , with type size_t—an implementation-defined unsigned type declared in <stddef.h> for C and <cstddef> for C++. The operator does not evaluate its operand (and thus ignores any side effects), except for variable-length arrays in C, where the size may be determined at . In C++, the core sizeof operator remains unary and cannot be overloaded, though an extended form sizeof... (identifier) exists to yield the number of elements in a template parameter pack as a size_t value. Applying sizeof to an expression of incomplete type (including void), function type, or bit-field (in C++11 and later) results in ; operands must designate complete types where applicable. The following code snippets illustrate basic usage:
c
sizeof(int);  // Yields the size of the `int` type in bytes
c
sizeof *ptr;  // Yields the size of the type pointed to by `ptr`

Usage

Arithmetic Types

In C and C++, the sizeof operator applied to arithmetic types yields the size in bytes of the storage required for those types, which is implementation-defined beyond certain minimum guarantees specified in the language standards. The fundamental arithmetic types include integer types (such as char, short, int, and long) and floating-point types (such as float and double). For integer types, the C99 standard mandates that sizeof(char) equals 1 byte (8 bits), while sizeof(short) is at least 2 bytes, sizeof(int) is at least 2 bytes, and sizeof(long) is at least 4 bytes; typical implementations on 32-bit or 64-bit systems use 2 bytes for short, 4 bytes for int, and 4 or 8 bytes for long, respectively. Similarly, floating-point types typically require 4 bytes for float and 8 bytes for double, though these sizes align with implementation choices often following IEEE 754 conventions for precision and range. Signed and unsigned variants of the same type occupy identical sizes, as the standards treat them as having the same representation width, differing only in value interpretation (e.g., for signed types). For example, sizeof(signed [int](/page/INT)) equals sizeof(unsigned [int](/page/INT)), both typically 4 bytes on common platforms. types (enum) in have an implementation-defined size that is compatible with an integer type, defaulting to the size of [int](/page/INT) in most compilers, ensuring they can hold the declared enumerator values without . Due to these platform dependencies, code relying on specific sizes risks portability issues; for instance, sizeof(long) may be 4 bytes on 32-bit x86 systems but 8 bytes on 64-bit systems. To mitigate this, the standard introduces fixed-width integer types via the <stdint.h> header, such as int32_t (exactly 32 bits if supported) and uint64_t, which provide consistent sizes across implementations where available. An example demonstrating typical sizes is:
c
#include <stdio.h>

int main() {
    printf("sizeof(char): %zu\n", sizeof(char));      // 1
    printf("sizeof(short): %zu\n", sizeof(short));    // 2
    printf("sizeof([int](/page/INT)): %zu\n", sizeof([int](/page/INT)));        // 4
    printf("sizeof(long): %zu\n", sizeof(long));      // 4 or 8
    printf("sizeof(float): %zu\n", sizeof(float));    // 4
    printf("sizeof(double): %zu\n", sizeof(double));  // 8
    return 0;
}
These values should be verified on the target architecture, as they reflect common but non-guaranteed configurations.

Pointers and Arrays

The sizeof operator applied to a pointer yields the size in bytes required to store a , which is independent of the pointed-to type and typically equals 4 bytes on 32-bit systems or 8 bytes on 64-bit systems. This size is implementation-defined by the , as pointers to different types may vary but are usually uniform within a given . (Section 6.2.5) For array objects of complete type, sizeof returns the total in bytes, computed as the product of the number of elements and the size of each element. (Section 6.5.3.4) For instance, in the declaration int arr[10];, assuming sizeof(int) is 4 bytes, sizeof(arr) evaluates to 40 bytes at . Taking the address of the first element, as in sizeof(&arr[0]), however, returns the size of a pointer to int, not the full .
c
#include <stdio.h>

int main() {
    int arr[10];
    [printf](/page/Printf)("sizeof(arr): %zu\n", sizeof(arr));      // 40 (on typical [32](/page/32)/64-bit system)
    [printf](/page/Printf)("sizeof(&arr[0]): %zu\n", sizeof(&arr[0])); // 4 or 8 (pointer size)
    [return 0](/page/Return_0);
}
A key distinction arises with array-to-pointer decay: except in specific contexts like the of sizeof or &, an lvalue of array type converts to a pointer to its initial element. (Section 6.3.2.1) Thus, when an array is passed to a function, the parameter type is adjusted to a pointer, causing sizeof inside the function to yield the pointer size rather than the array's total size. This pitfall often leads to incorrect assumptions about array length in functions. To compute the number of elements in a non-decayed array, the expression sizeof(arr) / sizeof(arr[0]) provides the count, as it divides the total bytes by the bytes per element. Multidimensional arrays are handled as arrays of arrays, so sizeof computes the total contiguous block size by multiplying all dimensions by the element size. For example, int matrix[3][4]; has size 3 * 4 * sizeof(int) or 48 bytes if int is 4 bytes, treating the entire structure as a single allocation.
c
#include <stdio.h>

int main() {
    int matrix[3][4];
    printf("sizeof(matrix): %zu\n", sizeof(matrix)); // 48 (assuming int=4 bytes)
    printf("Number of rows: %zu\n", sizeof(matrix) / sizeof(matrix[0])); // 3
    printf("Elements per row: %zu\n", sizeof(matrix[0]) / sizeof(matrix[0][0])); // 4
    return 0;
}
Introduced in C99, variable-length arrays (VLAs) permit runtime-determined sizes via expressions. (Section 6.7.5.2) Unlike fixed-length arrays, sizeof on a VLA is evaluated at runtime if its size depends on a non-constant expression, yielding the actual allocated bytes based on the evaluated dimensions. (Section 6.5.3.4) VLAs decay to pointers in function parameters similarly to fixed arrays, limiting sizeof utility inside functions.
c
#include <stdio.h>

int main() {
    int n = 5;
    int vla[n];  // VLA with runtime size
    [printf](/page/Printf)("sizeof(vla): %zu\n", sizeof(vla)); // 20 (5 * sizeof(int)=4)
    return 0;
}

Structures and Unions

The size of a type in C is determined by the sum of the sizes of its members, plus any unnamed bytes added within the or at to satisfy requirements. According to subclause 6.7.2.1 of the standard, may be inserted between members or after the last member so that each member begins at an offset that is a multiple of its alignment requirement, and the overall size is a multiple of the 's . This ensures efficient access and compatibility with arrays of the type. The of the itself is the of the alignments of its members, typically equal to the largest among them. For example, consider the following on a where char has 1-byte and int has 4-byte :
c
struct example {
    [char](/page/Char) a;  // 1 byte
    [int](/page/INT) b;   // 4 bytes
};
Here, sizeof(struct example) evaluates to 8 bytes. The [char](/page/Char) member occupies the first byte at offset 0, followed by 3 bytes of to align the [int](/page/INT) member to a 4-byte boundary at offset 4, with the total size padded to 8 bytes for . Padding mechanics, such as these insertions, are added to enforce natural rules, with further details covered in the implementation section on and . When a contains a nested as a member, the is performed recursively using the complete type of the inner , incorporating its own member sizes and any required . The of the nested within the outer one must respect the of the inner 's type, potentially introducing additional before it. This recursive approach ensures that the overall remains valid for access. The of a is sufficient to contain any of its members, equal to the of the largest member (by byte count), plus possible at the end to achieve the union's requirement. Per standard subclause 6.7.2.1, the of the is the maximum of its members, and all members share the same starting within the union object. Thus, smaller members overlap with the storage of larger ones, optimizing space for variant data. Introduced in the standard (subclause 6.7.2.1), a allows the last element of a to be an incomplete array type (e.g., int data[];), enabling variable-length objects. The sizeof operator applied to such a yields the offset and size up to but excluding the , as if it were omitted, though trailing padding may be added based on the 's . For instance:
c
struct flex {
    int count;
    char data[];  // [Flexible array member](/page/Flexible_array_member)
};
sizeof(struct flex) equals sizeof(int) (typically 4 bytes), ignoring the data array. To position the flexible array, use offsetof(struct flex, data), which gives the byte offset after fixed members. Memory allocation for an instance with n elements requires sizeof(struct flex) + n * sizeof(char). Alignment rules for structures and unions dictate that each member's starting address must be a multiple of its alignment value, which for fundamental types is usually equal to their size (e.g., 4 bytes for int on 32-bit systems). The sizeof operator accounts for these rules in computing the total size, ensuring the aggregate type can be stored and accessed efficiently without violating hardware constraints.

Incomplete Types

Incomplete types in C and C++ are object types that lack sufficient information to determine the size required for objects of that type, such as the void type, arrays of unknown size, or structures and unions declared via without a subsequent definition. The sizeof operator yields or a when applied to an incomplete type, as the standard prohibits its use on such types to avoid indeterminate results. In C, this constitutes a violation requiring a diagnostic message from the (section 6.5.3.4). In C++, the program is ill-formed, leading to a compile-time ([expr.sizeof]). The same restriction applies to types, where sizeof cannot be used directly, though sizeof on a yields the size of the pointer itself. For void, an incomplete type by definition, sizeof(void) is likewise prohibited in both languages. This behavior is illustrated in code attempting to apply sizeof to a forward-declared :
c
struct foo;  // Forward declaration: incomplete type

size_t s = sizeof(struct foo);  // Compilation error: invalid application of 'sizeof' to incomplete type
Compilers such as report an error like "invalid application of ‘sizeof’ to incomplete type ‘struct foo’". Incomplete types are commonly employed in header files to implement opaque pointers, where the full definition is hidden in the implementation file to enforce and prevent direct access to internal details. A prominent example is the FILE type in <stdio.h>, defined as an incomplete to allow library implementers to control its layout without exposing it to user code; thus, sizeof(FILE) is not permitted in application code. Regarding standards evolution, the C89 standard (ISO/IEC 9899:1989) imposed the same strict prohibition on sizeof for incomplete types, function types, and void as subsequent revisions. (ISO/IEC 9899:1999) retained this rule but introduced variable-length arrays (), which are complete types whose size may be determined at runtime. For a VLA, sizeof evaluates to a non-constant expression based on the runtime value of the size expression. (Section 6.5.3.4) This VLA exception does not extend to other incomplete types, and (ISO/IEC 9899:2011) made VLA support optional while preserving the core constraints. In C++, the rules have remained consistent across standards, with no VLA support and ill-formed status for all such cases.

Object Members

When applying the sizeof operator to a specific member of an object, such as sizeof(structobj.member) or sizeof(obj->member), it evaluates to the size in bytes of the type of that member, without evaluating the member expression itself beyond determining its type. This holds for non-static data members in structs, classes, or unions, providing the size of the member's declared type regardless of the enclosing object's layout. For bit-fields, which are members declared with a bit width (e.g., int flag : 1;), applying the sizeof operator directly to a bit-field lvalue is invalid in both C and C++, as bit-fields do not have a size independent of the containing struct, union, or class. Bit-field allocation, packing, and alignment are implementation-defined. The macro from <cstddef> works in tandem with sizeof to determine member positions and extents, particularly in low-level operations like or memory mapping. For a standard-layout struct, offsetof(type, member) returns the byte from the struct's start to the member (always 0 for the first non-static member), while sizeof provides the member's ; their combination enables calculating spans, such as for packing into buffers without assumptions. For instance, in struct Example { char a; [double](/page/Double) b; };, offsetof(Example, b) is typically 8 (due to alignment after a), and sizeof(Example::b) is 8. When a struct member is an , sizeof on that member returns the total byte of the , computed as the type multiplied by the . This is useful for fixed-size embedded in objects, such as struct Buffer { [int](/page/INT) data[10]; }; where sizeof(buf.data) equals 40 on platforms with 4-byte [int](/page/INT). In , sizeof applied to a specific member returns the of that member's type, which can be smaller than the 's overall (padded to fit the largest member). For example, in union Variant { [int](/page/INT) i; [double](/page/Double) d; };, sizeof(unionobj.i) is typically 4, while the is 8 to accommodate d. C++ extends this with class-specific features; for instance, sizeof on a non-static data member that is a pointer (common in implementations for virtual bases or vtable access) yields the platform's pointer size, usually sizeof(void*) at 8 bytes on 64-bit systems. Virtual base classes introduce indirect pointer members for shared subobjects, but sizeof on such a derived member's type follows the pointer size rule without exposing layout details.

Variadic Template Packs

In C++11 and later, variadic templates allow functions and classes to accept a variable number of template arguments through parameter packs, denoted by ellipsis syntax such as typename... Args. The sizeof... operator specifically queries the number of types in such a pack, returning a compile-time constant of type std::size_t, rather than the byte size of the types themselves. This operator is essential for tasks that require knowing the pack's without expanding it. To compute the total byte size of types in a variadic pack, sizeof can be applied to each pack element during expansion, often using recursive templates or, in C++17 and later, fold expressions for conciseness. For instance, a recursive approach might define a base case for an empty pack and accumulate sizes by unpacking the pack head and tail. In C++17, fold expressions simplify this with right-fold syntax, as in the following example:
cpp
#include <cstddef>

template<typename... Ts>
constexpr std::size_t total_size() {
    return (sizeof(Ts) + ... + 0);
}
This computes the sum of sizeof(Ts) for all types in the pack Ts at compile time. Integration with type traits from <type_traits> extends sizeof usage for array packs, where std::extent<T, N> retrieves the size of the Nth dimension of an array type T, and std::rank<T> gives the array's dimensionality. These can be combined in variadic templates to calculate total elements or storage needs for packs of arrays, such as determining the product of extents across multiple array types. A key limitation is that sizeof...(T) is ill-formed if T is not a parameter pack, requiring explicit pack identification and expansion in . Prior to , variadic templates were unavailable, so developers relied on alternatives like recursive template instantiations with fixed maximum or for type lists to simulate variable arguments in .

Implementation

Size Determination

The sizeof operator in and C++ determines the size of a complete object or type at by computing the total number of bytes required, based on the target's (ABI). For primitive types such as int, char, or float, the retrieves predefined sizes from ABI specifications or internal macros, ensuring consistency with the platform's memory model; for instance, in the LP64 ABI commonly used on 64-bit systems, int is 4 bytes, while long and pointers are 8 bytes. These primitive sizes serve as the foundation for more complex types. For aggregate types like structures, unions, and , the computation proceeds recursively by summing the sizes of constituent members or elements, incorporating adjustments as dictated by the ABI to ensure proper memory access. In C++, the ABI exemplifies this for classes, where the non-virtual size (nvsize) is calculated first from bases and members in declaration order, followed by inclusion of virtual bases to derive the full sizeof; primitives and bases are handled via their inherent ABI sizes, with the process updating a running total rounded to the type's boundary. Similarly, in C, the GNU Compiler Collection () employs target-specific macros like INT_TYPE_SIZE for primitives and recursively applies them to aggregates during type layout. This recursive approach guarantees that the result reflects the complete object's representation without evaluating the operand itself. The result of sizeof is always of type size_t, an unsigned integer type defined in <stddef.h> that is implementation-defined but guaranteed to hold the maximum size of any possible object on the target platform, typically matching the width of a pointer or larger to accommodate extensive allocations. In compiler implementations, sizeof maps directly to internal type information tables or descriptors, such as GCC's tree nodes representing type sizes in bits, converted to bytes via BITS_PER_UNIT. During cross-compilation, the enforces ABI by selecting appropriate macros and configurations, such as LP64 for 64-bit targets, to ensure sizeof yields values matching the rather than the host; mismatches can arise if host and target ABIs differ, but tools like GCC's multilib support mitigate this by building separate binaries. Compilers also issue diagnostics for unexpected sizes stemming from non-standard extensions, such as GNU-specific attributes altering type layouts, via flags like -pedantic or -Wextensions to alert developers to potential portability issues.

Padding and Alignment

In computer programming, particularly in C and C++, data alignment refers to the requirement that objects of certain types must be placed at memory addresses that are multiples of a specific value, known as the alignment requirement. This value is typically a power of two, such as 1, 2, 4, or 8 bytes, and is often equal to the size of the type itself or dictated by the application binary interface (ABI) rules of the platform. For instance, an integer type like int commonly requires alignment to a 4-byte boundary on 32-bit systems to enable efficient access by the processor. The sizeof accounts for by incorporating bytes into the calculated of aggregate types like structures and unions. is inserted between members to ensure each subsequent member starts at an address that satisfies its requirement; for example, following a 1-byte char member, up to 7 bytes of may be added before an 8-byte double to align the latter properly. Additionally, trailing is often added at the end of a to make its total a multiple of the 's requirement, which facilitates efficient layout when the is used in . This ensures that all elements of an of such remain properly aligned without additional adjustments. In unions, is minimal and typically limited to any necessary bytes beyond the of the largest member to meet the union's , which is the maximum among its members; since members overlap at the same starting address, no internal between members is required. Compilers provide mechanisms to control and , such as the implementation-defined directive and C++, which allows programmers to specify a maximum alignment boundary for structure members, effectively reducing or eliminating . For example, #pragma pack(1) packs members tightly with no , useful for interfacing with or serialized formats where exact byte layouts are critical. However, disabling can lead to unaligned , which may cause portability issues or errors on architectures that do not support it. While padding increases the result of sizeof and thus memory consumption, it enhances performance by enabling faster memory access patterns that align with hardware capabilities, avoiding penalties such as multiple bus cycles or exceptions for unaligned reads and writes. On modern processors, unaligned access can degrade performance significantly, sometimes by factors of 2 to 10, depending on the architecture. Consider the following structure example on a typical 64-bit system where double aligns to 8 bytes:
c
struct Example {
    char c;    // 1 byte
    double d;  // 8 bytes, requires 7 bytes of padding after c
};           // Plus 0 bytes trailing padding (total size multiple of 8)
Here, sizeof(struct Example) evaluates to 16 bytes, including 7 bytes of padding after the char to align the double. The C11 and C++11 standards formalize alignment querying through the _Alignof (C) and alignof (C++) operators, respectively, which return the alignment requirement of a type as a complement to sizeof. These operators apply to complete types and help predict padding needs; for aggregates, the alignment is the strictest (largest) among their members.

References

  1. [1]
    sizeof Operator (C) - Microsoft Learn
    Aug 3, 2021 · The `sizeof` operator gives the storage in bytes required to store an object of a type, and for arrays, the size of the entire array.
  2. [2]
    sizeof operator - cppreference.com - C++ Reference
    Dec 29, 2024 · The `sizeof` operator queries the size in bytes of an object or type, used when the actual size of the object must be known.
  3. [3]
    The sizeof operator - IBM
    The sizeof operator applied to a type name yields the amount of memory that can be used by an object of that type, including any internal or trailing padding.
  4. [4]
    The Development of the C Language - Nokia
    This paper is about the development of the C programming language, the influences on it, and the conditions under which it was created.
  5. [5]
    The GNU C Reference Manual
    This is a reference manual for the C programming language as implemented by the GNU Compiler Collection (GCC). ... sizeof Operator, Up: Expressions and Operators ...<|control11|><|separator|>
  6. [6]
  7. [7]
    The C Book — Sizeof and storage allocation - GBdirect
    The sizeof operator returns the size in bytes of its operand. Whether the result of sizeof is unsigned int or unsigned long is implementation defined.
  8. [8]
  9. [9]
    [PDF] ISO/IEC 9899:1999(E) -- Programming Languages -- C
    4. International Standard ISO/IEC9899 was prepared by Joint Technical. Committee ISO/IEC JTC 1, Information technology, Subcommittee SC 22,. Programming ...
  10. [10]
    [PDF] ISO/IEC 9899:201x
    Apr 12, 2011 · This International Standard specifies the form and establishes the interpretation of programs expressed in the programming language C. Its ...
  11. [11]
    EXP03-C. Do not assume the size of a structure is the ... - Confluence
    The size of a structure is not always equal to the sum of the sizes of its members. Subclause 6.7.2.1 of the C Standard states, "There may be unnamed padding ...
  12. [12]
    Alignment - Microsoft Learn
    Nov 2, 2023 · By default, the compiler aligns class and struct members on their size value: bool and char on 1-byte boundaries, short on 2-byte boundaries, ...
  13. [13]
    Use the correct syntax when declaring a flexible array member
    In most situations, the flexible array member is ignored. In particular, the size of the structure is as if the flexible array member were omitted except that ...
  14. [14]
    None
    Below is a merged summary of the `sizeof` operator and incomplete types from the C11 Draft (N1570), consolidating all information from the provided segments into a single, comprehensive response. To maximize density and clarity, I will use tables where appropriate to organize detailed information, followed by a narrative summary for additional context. The response retains all key details, including sections, behaviors, constraints, and URLs, while avoiding redundancy.
  15. [15]
    [PDF] N5001 - C++ - Open Standards
    Dec 17, 2024 · behavior (for example, sizeof(int)). These constitute the parameters of the abstract machine. Each implementation shall include ...
  16. [16]
    <stdio.h>
    Since the latest revision of the ISO C standard allows FILE to be an incomplete type (and POSIX also allows it), portable applications can no longer allocate or ...
  17. [17]
    sizeof operator - cppreference.com
    ### Summary of `sizeof` Operator from https://en.cppreference.com/w/c/language/sizeof
  18. [18]
    Bit-field - cppreference.com
    Feb 7, 2025 · In the C programming language, the width of a bit-field cannot exceed the width of the underlying type, and whether int bit-fields that are not ...
  19. [19]
    Bit-fields - cppreference.com
    ### Summary on `sizeof` Applied to Bit-Fields in C
  20. [20]
    offsetof - cppreference.com
    ### Summary: Use of `offsetof` with `sizeof` for Struct Members in Serialization Contexts
  21. [21]
  22. [22]
  23. [23]
    [PDF] Variadic Templates - Open Standards
    Feb 17, 2004 · The proposed resolution is to introduce a syntax and semantics for variable-length template argument lists (usable with function templates ...
  24. [24]
    Ellipsis and variadic templates | Microsoft Learn
    Sep 28, 2022 · A variadic template is a class or function template that supports an arbitrary number of arguments. This mechanism is especially useful to C++ library ...
  25. [25]
    Fold expressions (since C++17) - cppreference.com
    Dec 3, 2024 · Fold expressions reduce a pack over a binary operator, using syntax like (pack op ...). They can be unary or binary, right or left folds.
  26. [26]
  27. [27]
  28. [28]
    64-Bit Programming Models: Why LP64? - UNIX.org
    LLP64 preserves the relationship between int and long by leaving both as 32-bit datatypes. Objects not containing pointers will be the same size as on a 32-bit ...
  29. [29]
    17.6 Layout of Source Language Data Types
    GCC defines internal types ( sizetype , ssizetype , bitsizetype and sbitsizetype ) for expressions dealing with size. This macro is a C expression for a string ...
  30. [30]
    Itanium C++ ABI
    Then, round sizeof(C) up to a non-zero multiple of align(C). If C is a POD, but not a POD for the purpose of layout, set dsize(C) = nvsize(C) = sizeof(C).
  31. [31]
    Alignment (C11) - Microsoft Learn
    Oct 6, 2021 · Don't use a value smaller than the size of the type. struct and union types have an alignment equal to the largest alignment of any member.
  32. [32]
  33. [33]
    #pragma pack - IBM
    The #pragma pack directive modifies the current alignment rule for only the members of structures whose declarations follow the directive.<|separator|>
  34. [34]
    How to avoid Structure Padding in C? - GeeksforGeeks
    Jul 11, 2025 · Structure padding can be avoided in C using `#pragma pack(1)` or the `__attribute__((packed))` attribute.
  35. [35]
    Structure Member Alignment, Padding and Data Packing
    Jul 29, 2025 · Structure Padding in C ; Size of Structure A = Size of (char + short int) = 1 + 2 = 3. ; Size of Structure B = Size of (short int + char + int) = ...Structure Padding In C · Structure A · Structure C - Every...