Skip to content

Commit

Permalink
pw_toolchain: Document pw::ConstexprTag
Browse files Browse the repository at this point in the history
Change-Id: I4be5926f3367ec61bba0cffd452ba646e268aee8
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/265992
Lint: Lint 🤖 <[email protected]>
Commit-Queue: Wyatt Hepler <[email protected]>
Commit-Queue: Auto-Submit <[email protected]>
Reviewed-by: Erik Gilling <[email protected]>
Pigweed-Auto-Submit: Wyatt Hepler <[email protected]>
  • Loading branch information
255 authored and CQ Bot Account committed Feb 7, 2025
1 parent 0093c1c commit cbc2c8a
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 0 deletions.
2 changes: 2 additions & 0 deletions pw_toolchain/docs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ pw_toolchain/constexpr_tag.h
----------------------------
.. doxygenstruct:: pw::ConstexprTag

.. doxygenvariable:: pw::kConstexpr

pw_toolchain/globals.h
----------------------
.. doxygenclass:: pw::RuntimeInitGlobal
Expand Down
31 changes: 31 additions & 0 deletions pw_toolchain/public/pw_toolchain/constexpr_tag.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,40 @@

namespace pw {

/// Tag type used to differentiate between `constexpr` and non-`constexpr`
/// constructors. Do NOT use this feature for new classes! It should only be
/// used to add a `constexpr` constructor to an existing class in limited
/// circumstances.
///
/// Specifically, some compilers are more likely to constant initialize global
/// variables that have `constexpr` constructors. For large non-zero objects,
/// this can increase binary size compared to runtime initialization. Non-zero
/// constant initialized globals are typically placed in `.data` or `.rodata`
/// instead of `.bss`.
///
/// Adding `constexpr` to a constructor may affect existing users if their
/// compiler constant initializes globals that were runtime initialized
/// previously. To maintain previous behavior, add a new `constexpr` constructor
/// with `ConstexprTag` instead of changing the existing constructor.
///
/// Prefer using `pw::kConstexpr` to select a `constexpr`-tagged constructor,
/// rather than initializing a `pw::ConstexprTag`.
///
/// @warning Do NOT rely on whether a constructor is `constexpr` or not to
/// control whether global variables are constant initialized. To control
/// constant initialization, explicitly annotate global variables as `constinit`
/// / `PW_CONSTINIT`, `constexpr`, or `pw::RuntimeInitGlobal`. Compilers can
/// constant initialize globals that:
/// - are not declared `constinit` or `constexpr`,
/// - do not have a `constexpr` constructor,
/// - or perform non-`constexpr` actions during construction, such as calling
/// non-`constexpr` functions or placement new.
struct ConstexprTag {
explicit constexpr ConstexprTag() = default;
};

/// Value used to select a `constexpr` constructor tagged with
/// `pw::ConstexprTag`.
inline constexpr ConstexprTag kConstexpr{};

} // namespace pw

0 comments on commit cbc2c8a

Please sign in to comment.