]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Work around compiler trouble. 18229/head
authorWolfgang Bangerth <bangerth@colostate.edu>
Tue, 11 Mar 2025 23:15:02 +0000 (17:15 -0600)
committerWolfgang Bangerth <bangerth@colostate.edu>
Tue, 11 Mar 2025 23:15:02 +0000 (17:15 -0600)
source/base/utilities.cc

index 9f8b186db34b5906fdc4ec3b34ec9a6fe49af056..e41b50f622bfff0753e2bba642102adbcc1001ae 100644 (file)
@@ -662,6 +662,14 @@ namespace Utilities
     if ((s.size() > 0) && (s[0] == '+'))
       s.erase(s.begin());
 
+      // We want to use std::from_char() to do the conversion. That's a C++17
+      // function, but it turns out that some older compilers don't implement
+      // it correctly (notably GCC 9.x and clang 14) even though they claim
+      // to support C++17. We could try and test for individual compiler
+      // version, but it is probably enough to just select based on which C++
+      // standard we are compiling with -- every compiler that supports C++20
+      // should also have a complete implementation for std::from_chars().
+#ifdef DEAL_II_HAVE_CXX20
     // Now convert and see whether we succeed.
     double                       d;
     const std::from_chars_result result = std::from_chars(
@@ -681,6 +689,31 @@ namespace Utilities
                 ExcMessage("Can't convert <" + s + "> to a double."));
 
     return d;
+#else
+    // Now convert and see whether we succeed. Note that strtol only
+    // touches errno if an error occurred, so if we want to check
+    // whether an error happened, we need to make sure that errno==0
+    // before calling strtol since otherwise it may be that the
+    // conversion succeeds and that errno remains at the value it
+    // was before, whatever that was.
+    char *p;
+    errno          = 0;
+    const double d = std::strtod(s.c_str(), &p);
+
+    // We have an error if one of the following conditions is true:
+    // - strtod sets errno != 0
+    // - The original string was empty (we could have checked that
+    //   earlier already)
+    // - The string has non-zero length and strtod converted the
+    //   first part to something useful, but stopped converting short
+    //   of the terminating '\0' character. This happens, for example,
+    //   if the given string is "1.234 abc".
+    AssertThrow(!((errno != 0) || (s.empty()) ||
+                  ((s.size() > 0) && (*p != '\0'))),
+                ExcMessage("Can't convert <" + s + "> to a double."));
+
+    return d;
+#endif
   }
 
 

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.