Getting started with C++TemplatesMetaprogrammingIteratorsReturning several values from a functionstd::stringNamespacesFile I/OClasses/StructuresSmart PointersFunction Overloadingstd::vectorOperator OverloadingLambdasLoopsstd::mapThreadingValue CategoriesPreprocessorSFINAE (Substitution Failure Is Not An Error)The Rule of Three, Five, And ZeroRAII: Resource Acquisition Is InitializationExceptionsImplementation-defined behaviorSpecial Member FunctionsRandom number generationReferencesSortingRegular expressionsPolymorphismPerfect ForwardingVirtual Member FunctionsUndefined BehaviorValue and Reference SemanticsOverload resolutionMove SemanticsPointers to membersPimpl Idiomstd::function: To wrap any element that is callableconst keywordautostd::optionalCopy ElisionBit OperatorsFold ExpressionsUnionsUnnamed typesmutable keywordBit fieldsstd::arraySingleton Design PatternThe ISO C++ StandardUser-Defined LiteralsEnumerationType ErasureMemory managementBit ManipulationArraysPointersExplicit type conversionsRTTI: Run-Time Type InformationStandard Library AlgorithmsFriend keywordExpression templatesScopesAtomic Typesstatic_assertoperator precedenceconstexprDate and time using <chrono> headerTrailing return typeFunction Template OverloadingCommon compile/linker errors (GCC)Design pattern implementation in C++Optimization in C++Compiling and BuildingType Traitsstd::pairKeywordsOne Definition Rule (ODR)Unspecified behaviorFloating Point ArithmeticArgument Dependent Name Lookupstd::variantAttributesInternationalization in C++ProfilingReturn Type CovarianceNon-Static Member FunctionsRecursion in C++Callable Objectsstd::iomanipConstant class member functionsSide by Side Comparisons of classic C++ examples solved via C++ vs C++11 vs C++14 vs C++17The This PointerInline functionsCopying vs AssignmentClient server examplesHeader FilesConst Correctnessstd::atomicsData Structures in C++Refactoring TechniquesC++ StreamsParameter packsLiteralsFlow ControlType KeywordsBasic Type KeywordsVariable Declaration KeywordsIterationtype deductionstd::anyC++11 Memory ModelBuild SystemsConcurrency With OpenMPType Inferencestd::integer_sequenceResource Managementstd::set and std::multisetStorage class specifiersAlignmentInline variablesLinkage specificationsCuriously Recurring Template Pattern (CRTP)Using declarationTypedef and type aliasesLayout of object typesC incompatibilitiesstd::forward_listOptimizationSemaphoreThread synchronization structuresC++ Debugging and Debug-prevention Tools & TechniquesFutures and PromisesMore undefined behaviors in C++MutexesUnit Testing in C++Recursive MutexdecltypeUsing std::unordered_mapDigit separatorsC++ function "call by value" vs. "call by reference"Basic input/output in c++Stream manipulatorsC++ ContainersArithmitic Metaprogramming

Alignment

Other topics

Remarks:

The standard guarantees the following:

  • The alignment requirement of a type is a divisor of its size. For example, a class with size 16 bytes could have an alignment of 1, 2, 4, 8, or 16, but not 32. (If a class's members only total 14 bytes in size, but the class needs to have an alignment requirement of 8, the compiler will insert 2 padding bytes to make the class's size equal to 16.)
  • The signed and unsigned versions of an integer type have the same alignment requirement.
  • A pointer to void has the same alignment requirement as a pointer to char.
  • The cv-qualified and cv-unqualified versions of a type have the same alignment requirement.

Note that while alignment exists in C++03, it was not until C++11 that it became possible to query alignment (using alignof) and control alignment (using alignas).

Querying the alignment of a type

c++11

The alignment requirement of a type can be queried using the alignof keyword as a unary operator. The result is a constant expression of type std::size_t, i.e., it can be evaluated at compile time.

#include <iostream>
int main() {
    std::cout << "The alignment requirement of int is: " << alignof(int) << '\n';
}

Possible output

The alignment requirement of int is: 4

If applied to an array, it yields the alignment requirement of the element type. If applied to a reference type, it yields the alignment requirement of the referenced type. (References themselves have no alignment, since they are not objects.)

Controlling alignment

C++11

The alignas keyword can be used to force a variable, class data member, declaration or definition of a class, or declaration or definition of an enum, to have a particular alignment, if supported. It comes in two forms:

  • alignas(x), where x is a constant expression, gives the entity the alignment x, if supported.
  • alignas(T), where T is a type, gives the entity an alignment equal to the alignment requirement of T, that is, alignof(T), if supported.

If multiple alignas specifiers are applied to the same entity, the strictest one applies.

In this example, the buffer buf is guaranteed to be appropriately aligned to hold an int object, even though its element type is unsigned char, which may have a weaker alignment requirement.

alignas(int) unsigned char buf[sizeof(int)];
new (buf) int(42);

alignas cannot be used to give a type a smaller alignment than the type would have without this declaration:

alignas(1) int i; //Il-formed, unless `int` on this platform is aligned to 1 byte.
alignas(char) int j; //Il-formed, unless `int` has the same or smaller alignment than `char`.

alignas, when given an integer constant expression, must be given a valid alignment. Valid alignments are always powers of two, and must be greater than zero. Compilers are required to support all valid alignments up to the alignment of the type std::max_align_t. They may support larger alignments than this, but support for allocating memory for such objects is limited. The upper limit on alignments is implementation dependent.

C++17 features direct support in operator new for allocating memory for over-aligned types.

Contributors

Topic Id: 9249

Example Ids: 17475,17909

This site is not affiliated with any of the contributors.