diff mbox

Add const char* constructors for exception classes in <stdexcept>

Message ID 1387411826.2455.325.camel@yam-132-YW-E178-FTW
State New
Headers show

Commit Message

Oleg Endo Dec. 19, 2013, 12:10 a.m. UTC
Hello,

When writing code such as
...
  throw std::logic_error ("cold coffee");
...
currently the construction of std::string happens in the code that
throws the exception, which results in code bloat.  Implementing the
const char* constructors as defined by C++11 fixes the issue.
I'm not sure whether the #if __cplusplus >= 201103L checks are required.
C++98 code could also benefit from the overloads.

Tested with 'make all' and 'make install', writing a hello world and
checking the asm output.

Cheers,
Oleg

libstdc++-v3/ChangeLog:

	* include/std/stdexcept (logic_error, domain_error, 
	invalid_argument, length_error, out_of_range, runtime_error, 
	range_error, overflow_error, underflow_error): Declare const 
	char* constructors.
	* src/c++98/stdexcept.cc (logic_error, domain_error, 
	invalid_argument, length_error, out_of_range, runtime_error, 
	range_error, overflow_error, underflow_error): Implement them.

Comments

Jonathan Wakely Dec. 19, 2013, 1:19 a.m. UTC | #1
On 19 December 2013 00:10, Oleg Endo wrote:
> Hello,
>
> When writing code such as
> ...
>   throw std::logic_error ("cold coffee");
> ...
> currently the construction of std::string happens in the code that
> throws the exception, which results in code bloat.  Implementing the
> const char* constructors as defined by C++11 fixes the issue.
> I'm not sure whether the #if __cplusplus >= 201103L checks are required.
> C++98 code could also benefit from the overloads.

I think there was some good reason we haven't added these yet, but I
can't remember it.

> Tested with 'make all' and 'make install', writing a hello world and
> checking the asm output.

For all patches we need to know that the libstdc++ testsuite passes too.
diff mbox

Patch

Index: libstdc++-v3/include/std/stdexcept
===================================================================
--- libstdc++-v3/include/std/stdexcept	(revision 206101)
+++ libstdc++-v3/include/std/stdexcept	(working copy)
@@ -58,9 +58,12 @@ 
 
   public:
     /** Takes a character string describing the error.  */
-    explicit 
+    explicit
     logic_error(const string& __arg);
-
+#if __cplusplus >= 201103L
+    explicit
+    logic_error(const char* __arg);
+#endif
     virtual ~logic_error() _GLIBCXX_USE_NOEXCEPT;
 
     /** Returns a C-style character string describing the general cause of
@@ -75,6 +78,9 @@ 
   {
   public:
     explicit domain_error(const string& __arg);
+#if __cplusplus >= 201103L
+    explicit domain_error(const char* __arg);
+#endif
     virtual ~domain_error() _GLIBCXX_USE_NOEXCEPT;
   };
 
@@ -83,6 +89,9 @@ 
   {
   public:
     explicit invalid_argument(const string& __arg);
+#if __cplusplus >= 201103L
+    explicit invalid_argument(const char* __arg);
+#endif
     virtual ~invalid_argument() _GLIBCXX_USE_NOEXCEPT;
   };
 
@@ -92,6 +101,9 @@ 
   {
   public:
     explicit length_error(const string& __arg);
+#if __cplusplus >= 201103L
+    explicit length_error(const char* __arg);
+#endif
     virtual ~length_error() _GLIBCXX_USE_NOEXCEPT;
   };
 
@@ -101,6 +113,9 @@ 
   {
   public:
     explicit out_of_range(const string& __arg);
+#if __cplusplus >= 201103L
+    explicit out_of_range(const char* __arg);
+#endif
     virtual ~out_of_range() _GLIBCXX_USE_NOEXCEPT;
   };
 
@@ -115,9 +130,12 @@ 
 
   public:
     /** Takes a character string describing the error.  */
-    explicit 
+    explicit
     runtime_error(const string& __arg);
-
+#if __cplusplus >= 201103L
+    explicit
+    runtime_error(const char* __arg);
+#endif
     virtual ~runtime_error() _GLIBCXX_USE_NOEXCEPT;
 
     /** Returns a C-style character string describing the general cause of
@@ -131,6 +149,9 @@ 
   {
   public:
     explicit range_error(const string& __arg);
+#if __cplusplus >= 201103L
+    explicit range_error(const char* __arg);
+#endif
     virtual ~range_error() _GLIBCXX_USE_NOEXCEPT;
   };
 
@@ -139,6 +160,9 @@ 
   {
   public:
     explicit overflow_error(const string& __arg);
+#if __cplusplus >= 201103L
+    explicit overflow_error(const char* __arg);
+#endif
     virtual ~overflow_error() _GLIBCXX_USE_NOEXCEPT;
   };
 
@@ -147,6 +171,9 @@ 
   {
   public:
     explicit underflow_error(const string& __arg);
+#if __cplusplus >= 201103L
+    explicit underflow_error(const char* __arg);
+#endif
     virtual ~underflow_error() _GLIBCXX_USE_NOEXCEPT;
   };
 
Index: libstdc++-v3/src/c++98/stdexcept.cc
===================================================================
--- libstdc++-v3/src/c++98/stdexcept.cc	(revision 206101)
+++ libstdc++-v3/src/c++98/stdexcept.cc	(working copy)
@@ -36,6 +36,11 @@ 
   logic_error::logic_error(const string& __arg)
   : exception(), _M_msg(__arg) { }
 
+#if __cplusplus >= 201103L
+  logic_error::logic_error(const char* __arg)
+  : exception(), _M_msg(__arg) { }
+#endif
+
   logic_error::~logic_error() _GLIBCXX_USE_NOEXCEPT { }
 
   const char*
@@ -45,26 +50,51 @@ 
   domain_error::domain_error(const string& __arg)
   : logic_error(__arg) { }
 
+#if __cplusplus >= 201103L
+  domain_error::domain_error(const char* __arg)
+  : logic_error(__arg) { }
+#endif
+
   domain_error::~domain_error() _GLIBCXX_USE_NOEXCEPT { }
 
   invalid_argument::invalid_argument(const string& __arg)
   : logic_error(__arg) { }
 
+#if __cplusplus >= 201103L
+  invalid_argument::invalid_argument(const char* __arg)
+  : logic_error(__arg) { }
+#endif
+
   invalid_argument::~invalid_argument() _GLIBCXX_USE_NOEXCEPT { }
 
   length_error::length_error(const string& __arg)
   : logic_error(__arg) { }
 
+#if __cplusplus >= 201103L
+  length_error::length_error(const char* __arg)
+  : logic_error(__arg) { }
+#endif
+
   length_error::~length_error() _GLIBCXX_USE_NOEXCEPT { }
 
   out_of_range::out_of_range(const string& __arg)
   : logic_error(__arg) { }
 
+#if __cplusplus >= 201103L
+  out_of_range::out_of_range(const char* __arg)
+  : logic_error(__arg) { }
+#endif
+
   out_of_range::~out_of_range() _GLIBCXX_USE_NOEXCEPT { }
 
   runtime_error::runtime_error(const string& __arg)
   : exception(), _M_msg(__arg) { }
 
+#if __cplusplus >= 201103L
+  runtime_error::runtime_error(const char* __arg)
+  : exception(), _M_msg(__arg) { }
+#endif
+
   runtime_error::~runtime_error() _GLIBCXX_USE_NOEXCEPT { }
 
   const char*
@@ -74,16 +104,31 @@ 
   range_error::range_error(const string& __arg)
   : runtime_error(__arg) { }
 
+#if __cplusplus >= 201103L
+  range_error::range_error(const char* __arg)
+  : runtime_error(__arg) { }
+#endif
+
   range_error::~range_error() _GLIBCXX_USE_NOEXCEPT { }
 
   overflow_error::overflow_error(const string& __arg)
   : runtime_error(__arg) { }
 
+#if __cplusplus >= 201103L
+  overflow_error:overflow_error(const char* __arg)
+  : runtime_error(__arg) { }
+#endif
+
   overflow_error::~overflow_error() _GLIBCXX_USE_NOEXCEPT { }
 
   underflow_error::underflow_error(const string& __arg)
   : runtime_error(__arg) { }
 
+#if __cplusplus >= 201103L
+  underflow_error::underflow_error(const char* __arg)
+  : runtime_error(__arg) { }
+#endif
+
   underflow_error::~underflow_error() _GLIBCXX_USE_NOEXCEPT { }
 
 _GLIBCXX_END_NAMESPACE_VERSION