1. Introduction
There is ongoing disagreement and confusion around the phrase "trivially relocatable", as some C++ programmers intuitively think that it should mean that can relocated by simply doing a raw byte-by-byte copy from one memory location to another (for example by using , , or a simple loop with pointers).
This proposal removes the phrase "trivially relocatable" from the Standard and replaces it with an integer rating for relocatability. The following template function shall be added to the standard library:
namespace std { template < typename T > consteval int relocatability ( void ) noexcept { . . . } }
The integer returned from this function can have eleven possible values:
0 : cannot relocate 1 : relocate by memcpy/memmove 2 : relocate by implementation-specific built-in compiler algorithm that never throws 3 : relocate by static member function belonging to class (e.g.T::_Relocate) that never throws -3 : relocate by static member function belonging to class (e.g.T::_Relocate) that might throw 4 : relocate by nothrow-move and destroy -4 : relocate by move (might throw) and destroy 5 : relocate by nothrow-copy and destroy -5 : relocate by copy (might throw) and destroy 6 : relocate by nothrow-default-construction and nothrow-assignment and destroy -6 : relocate by default-construction (might throw) and assignment (might throw) and destroy
2. Motivation
Papers such as P3780 (Giuseppe D’Angelo) illustrate ongoing disagreement within the committee about the precise semantics of "trivial relocation". Some committee members feel that 'trivial' should mean that we can
the object’s bytes, while other committee members allow for the
invocation of implementation-specific relocation algorithms (for example
on the architecture, the re-signing of vtable pointers). These differing views hinder standardisation.
A numeric classification removes ambiguity by explicitly stating how a type can be relocated, instead of a binary yes/no notion.
3. Proposed API
namespace std { template < typename T > consteval int relocatability ( void ) noexcept { . . . } }
4. Custom-implemented Relocator
Here is an example of a class which provides its own reallocation algorithm:
struct File { int fd = -1 ; unsigned long relocation_count = 0u ; ... ... File ( void ) = default ; File ( File & ) = delete ; File ( File && ) = delete ; static void _Relocate ( File * const dest , File const * const src , std :: size_t const n ) noexcept { std :: memcpy ( dest , src , n * sizeof ( * dest ) ); . . . . . . for ( std :: size_t i = 0u ; i < n ; ++ i ) dest [ i ]. relocation_count += 1u ; } }; template < typename T > requires ( 0 < std :: relocatability < std :: remove_cvref_t < T > > () ) void MyFunction ( T && arg ) { // Works only for non-throwing relocatable types } static_assert ( 3 == std :: relocatability < File > () ); int main ( void ) { File f ; MyFunction ( f ); }
5. Implementation
A possible implementation:
template < typename T > consteval int relocatability ( void ) noexcept { if constexpr ( requires ( T * dst , T const * src , std :: size_t n ){ T :: _Relocate ( dst , src , n ); } ) { return noexcept ( T :: _Relocate (( T * ) nullptr ,( T * ) nullptr , 1u z )) ? 3 : -3 ; } else if constexpr ( /* . . arm64e stuff . . */ ) return 2 ; else if constexpr ( is_trivially_copyable_v < T > ) return 1 ; // memcpy/memmove else if constexpr ( is_destructible_v < T > ) { /**/ if constexpr ( is_nothrow_move_constructible_v < T > ) return 4 ; else if constexpr ( is_move_constructible_v < T > ) return -4 ; else if constexpr ( is_nothrow_copy_constructible_v < T > ) return 5 ; else if constexpr ( is_copy_constructible_v < T > ) return -5 ; else if constexpr ( is_nothrow_default_constructible_v < T > && is_nothrow_assignable_v < T & , T > ) return 6 ; else if constexpr ( is_default_constructible_v < T > && is_assignable_v < T & , T > ) return -6 ; } else return 0 ; }
6. Design Considerations
- Integer classification provides an ordered preference for relocation strategies.
- Signedness conveys exception-safety (positive =
).noexcept - Custom
allows user-defined relocation semantics.T :: _Relocate - Compiler built-ins (category 2) allow progressive adoption of new relocation optimisations.
7. Impact on the Standard
This proposal introduces a single, header-only library extension (), adds no new keywords, and provides a clear replacement for the ambiguous term "trivially relocatable". It has no breaking changes -- all pre-existing code will be unaffected.