C programs create, destroy, access, and manipulate objects.
An object in C is a region ofdata storage in the execution environment, the contents of which can representvalues (a value is the meaning of the contents of an object, when interpreted as having a specifictype).
Every object has
sizeof)_Alignof(until C23)alignof(since C23))(since C11)Objects are created bydeclarations,allocation functions,string literals,compound literals, and by non-lvalue expressions that returnstructures or unions with array members.
Contents |
Except forbit-fields, objects are composed of contiguous sequences of one or more bytes, each consisting ofCHAR_BIT bits, and can be copied withmemcpy into an object of typeunsignedchar[n], wheren is the size of the object. The contents of the resulting array are known asobject representation.
If two objects have the same object representation, they compare equal (except if they are floating-point NaNs). The reverse is not true: two objects that compare equal may have different object representations because not every bit of the object representation needs to participate in the value. Such bits may be used for padding to satisfy alignment requirement, for parity checks, to indicate trap representations, etc.
If an object representation does not represent any value of the object type, it is known astrap representation. Accessing a trap representation in any way other than reading it through an lvalue expression of character type is undefined behavior. The value of a structure or union is never a trap representation even if any particular member is one.
For the objects of typechar,signedchar, andunsignedchar, every bit of the object representation is required to participate in the value representation and each possible bit pattern represents a distinct value (no padding, trap bits, or multiple representations allowed).
When objects ofinteger types (short,int,long,longlong) occupy multiple bytes, the use of those bytes is implementation-defined, but the two dominant implementations arebig-endian (POWER, Sparc, Itanium) andlittle-endian (x86, x86_64): a big-endian platform stores the most significant byte at the lowest address of the region of storage occupied by the integer, a little-endian platform stores the least significant byte at the lowest address. SeeEndianness for detail. See also example below.
Although most implementations do not allow trap representations, padding bits, or multiple representations for integer types, there are exceptions; for example a value of an integer type on Itaniummay be a trap representation.
Every object has aneffective type, which determines whichlvalue accesses are valid and which violate the strict aliasing rules.
If the object was created by adeclaration, the declared type of that object is the object'seffective type.
If the object was created by anallocation function (includingrealloc), it has no declared type. Such object acquires an effective type as follows:
Given an object witheffective type T1, using an lvalue expression (typically, dereferencing a pointer) of a different type T2 is undefined behavior, unless:
These rules control whether when compiling a function that receives two pointers, the compiler must emit code that re-reads one after writing through another:
// int* and double* cannot aliasvoid f1(int* pi,double* pd,double d){// the read from *pi can be done only once, before the loopfor(int i=0; i<*pi; i++)*pd++= d;}
struct S{int a, b;}; // int* and struct S* may alias because S is an aggregate type with a member of type intvoid f2(int* pi,struct S* ps,struct S s){// read from *pi must take place after every write through *psfor(int i=0; i<*pi; i++)*ps++= s;}
Note thatrestrict qualifier can be used to indicate that two pointers do not alias even if the rules above permit them to be.
Note that type-punning may also be performed through the inactive member of aunion.
Every completeobject type has a property calledalignment requirement, which is an integer value of typesize_t representing the number of bytes between successive addresses at which objects of this type can be allocated. The valid alignment values are non-negative integral powers of two.
The alignment requirement of a type can be queried with | (since C11) |
In order to satisfy alignment requirements of all members of a struct, padding may be inserted after some of its members.
#include <stdalign.h>#include <stdio.h> // objects of struct S can be allocated at any address// because both S.a and S.b can be allocated at any addressstruct S{char a;// size: 1, alignment: 1char b;// size: 1, alignment: 1};// size: 2, alignment: 1 // objects of struct X must be allocated at 4-byte boundaries// because X.n must be allocated at 4-byte boundaries// because int's alignment requirement is (usually) 4struct X{int n;// size: 4, alignment: 4char c;// size: 1, alignment: 1// three bytes padding};// size: 8, alignment: 4 int main(void){printf("sizeof(struct S) = %zu\n",sizeof(struct S));printf("alignof(struct S) = %zu\n", alignof(struct S));printf("sizeof(struct X) = %zu\n",sizeof(struct X));printf("alignof(struct X) = %zu\n", alignof(struct X));}
Possible output:
sizeof(struct S) = 2alignof(struct S) = 1sizeof(struct X) = 8alignof(struct X) = 4
Each object type imposes its alignment requirement on every object of that type. The weakest (smallest) alignment is the alignment of the typeschar,signedchar, andunsignedchar, and equals1. The strictest (largest)fundamental alignment of any type is implementation-definedand equal to the alignment ofmax_align_t(since C11).
Fundamental alignments are supported for objects of all kinds of storage durations.
If an object's alignment is made stricter (larger) thanmax_align_t using If a struct or union type Theatomic version of everyarithmetic orpointer type has a fundamental alignment. | (since C11) |
The following behavior-changing defect reports were applied retroactively to previously published C standards.
| DR | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| DR 445 | C11 | a type might have extended alignment without_Alignas involved | it must have fundamental alignment |
C++ documentation forObject |