Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / outcome / doc / src / content / faq / _index.md
index 0baf18d..0b5745c 100644 (file)
@@ -417,36 +417,20 @@ interoperate with code using Outcome.
 
 ## Is Outcome riddled with undefined behaviour for const, const-containing and reference-containing types?
 
-The short answer is yes, but it probably won't matter to you in practice.
+The short answer is not any more in C++ 20 and after, thanks to changes made to
+C++ 20 at the Belfast WG21 meeting in November 2019.
 
-The longer answer is that the same problem affects lots of C++ out there,
-so lots of production code will break if Outcome ever breaks on this. The
-potentially sometime-in-the-future affected code sequence would be:
+The longer answer is that before C++ 20, use of placement
+new on types containing `const` member types where the resulting pointer was
+thrown away is undefined behaviour. As of the resolution of a national body
+comment, this is no longer the case, and now Outcome is free of this particular
+UB for C++ 20 onwards.
 
-```c++
-struct const_containing_type
-{
-  const int no;                        // only concerns const and reference types
-  const_containing_type(int n) : no(n) {}
-};
-
-extern void external_function(int, const result<const_containing_type> &);
-
-int example_const_propagation2()
-{
-  result<const_containing_type> a{5};
-  const int &x = a.value().no;
-  external_function(x, a);             // might call an outcome function which calls placement new!
-  return x;                            // does this reload x, or assume it hasn't changed?
-}
-```
-
-GCCs up to v10, clangs up to v9 and MSVCs up to VS2019.1 <u><b>do</b></u> reload `x` after
-the call of an unknown function, even though it has constant type. This may change
-in future compilers due to changes in the C++ standard to encourage such
-optimisations.
+This still affects C++ before 20, though no major compiler is affected. Still,
+if you wish to avoid UB, don't use `const` types within Outcome types (or any
+`optional<T>`, or `vector<T>` or any STL container type for that matter).
 
-### Brief history of C++ standard changes
+### More detail
 
 Before the C++ 14 standard, placement new into storage which used to contain
 a const type was straight out always undefined behaviour, period. Thus all use of
@@ -491,30 +475,10 @@ undesirable given all the care and attention paid to keeping it small. The alter
 is to use {{% api "std::launder" %}}, which was added in C++ 17, to 'launder'
 the storage into which we placement new before each and every use of that
 storage. This forces the compiler to reload the object stored by placement
-new on every occasion, and not assume it is can be constant propagated, which
+new on every occasion, and not assume it can be constant propagated, which
 impacts codegen quality.
 
-As neither situation is obviously desirable, after much thought I have
-decided to simply do nothing apart from add this FAQ entry. I would say that
-because Outcome is 100% header-only, the compiler can always see the
-calls of placement new, and thus the compiler always knows that the
-preceding const or reference object is dead, and there is now a new const
-or reference object in its place. I appreciate that this is a hand waving
-response, and code using Outcome will still contain undefined behaviour if
-you use it with a const type, or a type containing const or reference types.
-
-However the reality on the ground is that a ton of production C++ code does
-placement new of types potentially containing const or reference types, and
-it is highly unlikely that C++ compilers will, in practice, break all that
-production code, especially as the template type supplied to library code is often
-outside one's control. If, however, compilers do end up moving ahead on
-optimising this aggressively, Outcome will need to add laundering for any
-type containing const or reference types, for which one needs Reflection
-into the language in any case. We shall thus wait until later to see what
-happens.
-
-### Summary
-
-If you wish to be kept abreast of changes on this topic, please add yourself
-to https://github.com/ned14/outcome/issues/185 which is the issue tracking
-this bug.
+As mentioned above, this issue (in so far as it applies to types containing
+user supplied `T` which might be `const`) has been resolved as of C++ 20 onwards,
+and it is extremely unlikely that any C++ compiler will act on any UB here in
+C++ 17 or 14 given how much of STL containers would break.