diff --git a/xml/issue4014.xml b/xml/issue4014.xml new file mode 100644 index 0000000000..13a6659b89 --- /dev/null +++ b/xml/issue4014.xml @@ -0,0 +1,201 @@ + + + + +LWG 3809 changes behavior of some existing <tt>std::subtract_with_carry_engine</tt> code +
+Matt Stephanson +15 Nov 2023 +99 + + +

+Issue pointed out that subtract_with_carry_engine<T> can be seeded with values +from a linear_congruential_engine<T, 40014u, 0u, 2147483563u> object, which results in narrowing +when T is less than 32 bits. Part of the resolution was to modify the LCG seed sequence as follows: +

+
+
explicit subtract_with_carry_engine(result_type value);
+

-7- Effects: +Sets the values of + + + X - r + , + + , + X - 1 + +, +in that order, as specified below. If + + + X - 1 + + +is then 0 , +sets c to 1 ; +otherwise sets c to 0 . +

+

     +To set the values + X k , +first construct e, a linear_congruential_engine object, +as if by the following definition: +

+
+linear_congruential_engine<result_typeuint_least32_t,
+                           40014u,0u,2147483563u> e(value == 0u ? default_seed : value);
+
+

     +Then, to set each + X k , +obtain new values + + + z 0 + , + + , + z n - 1 + + +from + + + n = + + w / 32 + + + +successive invocations of e. +Set + X k +to + + + + ( + + + j = 0 + n - 1 + + z j + + 2 32 j + ) + + mod + m + +. +

+
+

+Inside linear_congruential_engine, the seed is reduced modulo 2147483563, so uint_least32_t +is fine from that point on. This resolution, however, forces value, the user-provided seed, to be +truncated from result_type to uint_least32_t before the reduction, which generally will +change the result. It also breaks the existing behavior that two seeds are equivalent if they're in the same +congruence class modulo the divisor. +

+
+ + +

+This wording is relative to after the wording changes applied by LWG , +which had been accepted into the working paper during the Kona 2023-11 meeting. +

+ +
    + +
  1. Modify as indicated:

    + +
    +
    explicit subtract_with_carry_engine(result_type value);
    +

    -7- Effects: +Sets the values of + + + X - r + , + + , + X - 1 + +, +in that order, as specified below. If + + + X - 1 + + +is then 0 , +sets c to 1 ; +otherwise sets c to 0 . +

    +

         +To set the values + X k , +first construct e, a linear_congruential_engine object, +as if by the following definition: +

    +
    +linear_congruential_engine<uint_least32_t,
    +                           40014u,0u,2147483563u> e(value == 0u ? default_seed : 
    +                           static_cast<uint_least32_t>(value % 2147483563u));
    +
    +

         +Then, to set each + X k , +obtain new values + + + z 0 + , + + , + z n - 1 + + +from + + + n = + + w / 32 + + + +successive invocations of e. +Set + X k +to + + + + ( + + + j = 0 + n - 1 + + z j + + 2 32 j + ) + + mod + m + +. +

    +
    + +
  2. + +
+
+ +