pw_alignment#

Natural object alignment, guaranteed

Stable C++17

  • Transparent: Enforce natural alignment without any changes to how your objects are used.

  • Efficient: Prevent your compiler from emitting libcalls to builtin atomic functions and ensure it uses native atomic instructions instead.

#include "pw_alignment/alignment.h"

// Passing a `std::optional<bool>` to `__atomic_exchange` might not replace
// the call with native instructions if the compiler cannot determine all
// instances of this object will happen to be aligned.
std::atomic<std::optional<bool>> maybe_nat_aligned_obj;

// `pw::NaturallyAligned<...>` forces the object to be aligned to its size,
// so passing it to `__atomic_exchange` will result in a replacement with
// native instructions.
std::atomic<pw::NaturallyAligned<std::optional<bool>>> nat_aligned_obj;

// Shorter spelling for the same as above.
pw::AlignedAtomic<std::optional<bool>> also_nat_aligned_obj;

pw_alignment portably ensures that your compiler uses native atomic instructions rather than libcalls to builtin atomic functions. Take for example std::atomic<std::optional<bool>>. Accessing the underlying object normally involves a call to a builtin __atomic_* function. The problem is that the compiler sometimes can’t determine that the size of the object is the same as the size of its alignment. pw_alignment ensures that an object aligns to its size so that compilers can always make this optimization.

Warning

Using std::optional<bool> is only a workaround that may not work with all compilers. This specifically does not work when targetting ARM cortex M0. Additionally, std::optional<bool> is not the recommended way to represent a ternary variable.

Get Started

How to set up pw_alignment in your build system.

API Reference

Reference information about the pw_alignment API.

Get started#

Add @pigweed//pw_alignment to the deps list in your Bazel target:

cc_library("...") {
  # ...
  deps = [
    # ...
    "@pigweed//pw_alignment",
    # ...
  ]
}

Add $dir_pw_alignment to the deps list in your pw_executable() build target:

pw_executable("...") {
  # ...
  deps = [
    # ...
    "$dir_pw_alignment",
    # ...
  ]
}

Add pw_alignment to your pw_add_library or similar CMake target:

pw_add_library(my_library STATIC
  HEADERS
    ...
  PRIVATE_DEPS
    # ...
    pw_alignment
    # ...
)

API reference#

Moved: pw_alignment