Title
Remove undefined behaviour from `hive` for invalid limits
Status
immediate
Section
[hive.overview]
Submitter
Jonathan Wakely

Created on 2026-03-24.00:00:00 last changed 4 days ago

Messages

Date: 2026-03-26.15:45:51

Proposed resolution:

This wording is relative to N5032.

  1. Modify [hive.overview] as indicated:

    -5- Limits can be placed on both the minimum and maximum element capacities of element blocks, both by users and implementations.
    • (5.1) — The minimum limit shall be no larger than the maximum limit.
    • (5.2) — When limits are not specified by a user during construction, the implementation's default limits are used.
    • (5.3) — The default limits of an implementation are not guaranteed to be the same as the minimum and maximum possible capacities for an implementation's element blocks.
      [Note 2:  To allow latitude for both implementation-specific and user-directed optimization. — end note]
      The latter are defined as hard limits. The maximum hard limit shall be no larger than std::allocator_traits<Allocator>::max_size().
    • (5.4) — If user-specified limits passed to a `hive` constructor or `reshape` are not within hard limits, or if the specified minimum limit is greater than the specified maximum limit, the behavior is undefined erroneous and the effects are implementation-defined.
      [Note ?: This condition can be checked using `is_within_hard_limits`. — end note]
    • (5.5) — An element block is said to be within the bounds of a pair of minimum/maximum limits when its capacity is greater-or-equal-to the minimum limit and less-than-or-equal-to the maximum limit.
  2. Modify [hive.overview] as indicated:

      constexpr hive_limits block_capacity_limits() const noexcept;
      static constexpr hive_limits block_capacity_default_limits() noexcept;
      static constexpr hive_limits block_capacity_hard_limits() noexcept;
      static constexpr bool is_within_hard_limits(hive_limits) noexcept;
      void reshape(hive_limits block_limits);
    
  3. Modify [hive.capacity] as indicated:

    static constexpr hive_limits block_capacity_hard_limits() noexcept;

    -19- Returns: A `hive_limits` struct with the `min` and `max` members set to the implementation’s hard limits.

    static constexpr bool is_within_hard_limits(hive_limits lim) noexcept;

    -?- Let `hl` be `block_capacity_hard_limits()`.

    -?- Returns: hl.min <= lim.min && lim.min <= lim.max && lim.max <= hl.max.

Date: 2026-03-26.15:45:51

[ Croydon 2026-03-26; move to Immediate. ]

Date: 2026-03-15.00:00:00

[ 2026-03-26; Jonathan and Frank provide new wording ]

Provide a new static member function on hive which compares a `hive_limits` to its hard limits. Change behaviour from undefined to erroneous with implementation-defined effects.

Date: 2026-03-15.00:00:00

[ 2026-03-24; Jonathan adds wording ]

Could throw when the precondition is violated, or make it a Hardened Precondition, or ... something else? Three options are presented, which are not entirely mutually exclusive.

This wording is relative to N5032.

Option A - make `hive` check for invalid limits and throw

  1. Modify [hive.overview] as indicated:

    -5- Limits can be placed on both the minimum and maximum element capacities of element blocks, both by users and implementations.
    • (5.1) — The minimum limit shall be no larger than the maximum limit.
    • (5.2) — When limits are not specified by a user during construction, the implementation's default limits are used.
    • (5.3) — The default limits of an implementation are not guaranteed to be the same as the minimum and maximum possible capacities for an implementation's element blocks.

      [Note 2:  To allow latitude for both implementation-specific and user-directed optimization. — end note]

      The latter are defined as hard limits. The maximum hard limit shall be no larger than std::allocator_traits<Allocator>::max_size().
    • (5.4) — If user-specified limits are not within hard limits, or if the specified minimum limit is greater than the specified maximum limit, the behavior is undefined.
    • (5.5) — An element block is said to be within the bounds of a pair of minimum/maximum limits when its capacity is greater-or-equal-to the minimum limit and less-than-or-equal-to the maximum limit.
  2. Modify [hive.cons] as indicated:

    constexpr hive(hive_limits block_limits, const Allocator&);

    -3- Effects: Constructs an empty `hive`, using the specified allocator. Initializes `current-limits` with `block_limits`.

    -4- Complexity: Constant.

    -?- Throws: `invalid_argument` if `block_limits.min` or `block_limits.max` is outside the hard limits, or if `block_limits.min` is greater than `block_limits.max`.

    Similar changes to other constructors and `reshape`

Option B - provide a helper to make limits valid

  1. Modify [hive.syn] as indicated:

    namespace std {
      struct hive_limits {
        size_t min;
        size_t max;
        constexpr hive_limits(size_t minimum, size_t maximum) noexcept
          : min(minimum), max(maximum) {}
    
        constexpr hive_limits clamp_to(const hive_limits& lim) const noexcept
        { return {clamp(min, lim.min, lim.max), clamp(max, lim.min, lim.max)}; }
      };
    

Option C - add a helper to validate limits against hard limits and define Preconditions using it.

  1. Modify [hive.syn] as indicated:

    namespace std {
      struct hive_limits {
        size_t min;
        size_t max;
        constexpr hive_limits(size_t minimum, size_t maximum) noexcept
          : min(minimum), max(maximum) {}
    
        constexpr bool valid_for(const hive_limits& lim) const noexcept
        { return min <= max && lim.min <= min && max <= lim.max; }
      };
    
  2. Modify [hive.cons] as indicated:

    constexpr hive(hive_limits block_limits, const Allocator&);

    -?- Preconditions: `block_limits.valid_for(block_capacity_hard_limits())` is `true`.

    -3- Effects: Constructs an empty `hive`, using the specified allocator. Initializes `current-limits` with `block_limits`.

    -4- Complexity: Constant.

    Similar changes to other constructors and `reshape`
Date: 2026-03-24.00:00:00

Addresses US 139-232

[hive.overview] says:

-5- Limits can be placed on both the minimum and maximum element capacities of element blocks, both by users and implementations.
  • ...
  • (5.4) — If user-specified limits are not within hard limits, or if the specified minimum limit is greater than the specified maximum limit, the behavior is undefined.

The NB comment says:

Paragraph 5.4 allows for UB when the user doesn't manage to keep the block limits within bounds and the min below the max, yet no tools are offered to check these conditions easily. In terms of providing safe facilities this UB is an easy trap to fall into. The methods that allow to set block limits on hive should rather check the conditions and throw in case of violation or at least some function should be provided to let the user check the conditions easily.

Proposed change: Adjust all constructors and methods on hive to throw in case specified block limits violate the conditions set out here. Or at least provide a function to the user to correctly check the condition separately.

History
Date User Action Args
2026-03-26 15:45:51adminsetmessages: + msg16099
2026-03-26 15:45:51adminsetstatus: new -> immediate
2026-03-26 11:33:02adminsetmessages: + msg16093
2026-03-24 15:52:58adminsetmessages: + msg16055
2026-03-24 15:52:58adminsetmessages: + msg16054
2026-03-24 00:00:00admincreate