[Bug libstdc++/90246] New: std::bad_variant_access messages are not useful

redi at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Thu Apr 25 10:15:00 GMT 2019


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90246

            Bug ID: 90246
           Summary: std::bad_variant_access messages are not useful
           Product: gcc
           Version: 8.3.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: redi at gcc dot gnu.org
  Target Milestone: ---

Every exception of type bad_variant_access has the same unhelpful text:

"Unexpected index"

Seeing this in a log file tells you almost nothing. It would be much better to
say:

"std::visit<R> called on valueless variant"

or "std::get<1> called on variant with index 2"

This requires an ABI change, because bad_variant_access currently just stores a
const char* (which is assumed to point to a string with static storage
duration, e.g. a literal).

Something like this would allow us to store a (possibly dynamically allocated)
string in the exception object, so we can provide formatted strings with
additional information:

@@ -1200,13 +1278,21 @@ namespace __variant
   {
   public:
     bad_variant_access() noexcept : _M_reason("Unknown reason") { }
+
     const char* what() const noexcept override
-    { return _M_reason; }
+    { return _M_reason.get(); }

   private:
-    bad_variant_access(const char* __reason) : _M_reason(__reason) { }
+    // Must only be called with a string literal
+    bad_variant_access(const char* __reason, nullptr_t)
+    : _M_reason(__reason, [](const char*){})
+    { }
+
+    bad_variant_access(const char* __reason)
+    : _M_reason(std::strdup(__reason), [](const char* __s) { std::free(__s);
})
+    { }

-    const char* _M_reason;
+    __shared_ptr<const char[]> _M_reason;

     friend void __throw_bad_variant_access(const char* __what);
   };


More information about the Gcc-bugs mailing list