MySQL++

View Ticket
Login
Ticket Hash: 8395aa91d1231e072ebe93d59f159b2c0a0a8dcc
Title: C++17 does not allow dynamic exception specifications
Status: Closed Type: Code Defect
Severity: Severe Priority: Immediate
Subsystem: Library Resolution: Fixed
Last Modified: 2018-07-12 19:50:09
Version Found In: 3.2.3
User Comments:
anonymous added on 2018-05-01 22:02:58:
in beemutex.h and stadapter.h there are member functions declared like this:
void lock() throw (MutexFailed);

In C++17 mode in gcc, that generates "error: ISO C++17 does not allow dynamic exception specifications".

Some conditional compilation might be in order here to address this error.

tangent added on 2018-05-02 14:45:58:
> Some conditional compilation might be in order here

The trick is how to do that portably.

The wrong way is to simply test for a particular GCC version, since that doesn't test whether C++17 compatibility is enabled on any given build. It also wouldn't get you Clang or VC++ compatibility.

The right way is to create a set of Autoconf and C++ macro tests that end up defining macros like MYSQLPP_HAVE_CPP17, which in turn you could ifdef against to remove these throwspecs.

I can't just blindly remove the throwspecs, since I assume they affect the ABI of the built library. MySQL++ 3's ABI has been stable for many years now, so I don't want to break it now.

Patches will be thoughtfully considered if you have any idea of how to do this properly. Otherwise, I suggest that you just locally hack your copy of the library to remove the throwspecs.

anonymous added on 2018-05-02 16:34:27:
If you're compiling in C++17 mode you can't keep the ABI anyway because (as you note) the different throw spec, so here's a proposed patch:

diff --git a/mysql++-3.2.3/lib/beemutex.cpp b/mysql++-3.2.3/lib/beemutex.cpp
index bc6ba30..0f9c318 100644
--- a/mysql++-3.2.3/lib/beemutex.cpp
+++ b/mysql++-3.2.3/lib/beemutex.cpp
@@ -61,7 +61,11 @@ namespace mysqlpp {
 #endif
 
 
+#if __cplusplus < 201703L
+BeecryptMutex::BeecryptMutex() throw (MutexFailed)
+#else
 BeecryptMutex::BeecryptMutex() noexcept(false)
+#endif
 #if defined(ACTUALLY_DOES_SOMETHING)
        : pmutex_(new bc_mutex_t)
 #endif
@@ -103,7 +107,11 @@ BeecryptMutex::~BeecryptMutex()
 
 
 void
+#if __cplusplus < 201703L
+BeecryptMutex::lock() throw (MutexFailed)
+#else
 BeecryptMutex::lock() noexcept(false)
+#endif
 {
 #if defined(MYSQLPP_PLATFORM_WINDOWS)
        if (WaitForSingleObject(impl_val(pmutex_), INFINITE) == WAIT_OBJECT_0)
@@ -125,7 +133,11 @@ BeecryptMutex::lock() noexcept(false)
 
 
 bool
+#if __cplusplus < 201703L
+BeecryptMutex::trylock() throw (MutexFailed)
+#else
 BeecryptMutex::trylock() noexcept(false)
+#endif
 {
 #if defined(ACTUALLY_DOES_SOMETHING)
 #      if defined(MYSQLPP_PLATFORM_WINDOWS)
@@ -160,7 +172,11 @@ BeecryptMutex::trylock() noexcept(false)
 
 
 void
+#if __cplusplus < 201703L
+BeecryptMutex::unlock() throw (MutexFailed)
+#else
 BeecryptMutex::unlock() noexcept(false)
+#endif
 {
 #if defined(MYSQLPP_PLATFORM_WINDOWS)
        if (!ReleaseMutex(impl_val(pmutex_)))
diff --git a/mysql++-3.2.3/lib/beemutex.h b/mysql++-3.2.3/lib/beemutex.h
index a5850f3..0457950 100644
--- a/mysql++-3.2.3/lib/beemutex.h
+++ b/mysql++-3.2.3/lib/beemutex.h
@@ -61,7 +61,11 @@ public:
        ///
        /// Throws a MutexFailed exception if we can't acquire the lock for
        /// some reason.  The exception contains a message saying why.
+#if __cplusplus < 201703L
+       BeecryptMutex() throw (MutexFailed);
+#else
         BeecryptMutex() noexcept(false);
+#endif
 
        /// \brief Destroy the mutex
        ///
@@ -70,14 +74,26 @@ public:
 
        /// \brief Acquire the mutex, blocking if it can't be acquired
        /// immediately.
+#if __cplusplus < 201703L
+       void lock() throw (MutexFailed);
+#else
        void lock() noexcept(false);
+#endif
 
        /// \brief Acquire the mutex immediately and return true, or return
        /// false if it would have to block to acquire the mutex.
+#if __cplusplus < 201703L
+       bool trylock() throw (MutexFailed);
+#else
        bool trylock() noexcept(false);
+#endif
 
        /// \brief Release the mutex
+#if __cplusplus < 201703L
+       void unlock() throw (MutexFailed);
+#else
        void unlock() noexcept(false);
+#endif
 
 private:
        void* pmutex_;
diff --git a/mysql++-3.2.3/lib/stadapter.cpp b/mysql++-3.2.3/lib/stadapter.cpp
index a9e0641..5d15696 100644
--- a/mysql++-3.2.3/lib/stadapter.cpp
+++ b/mysql++-3.2.3/lib/stadapter.cpp
@@ -416,7 +416,11 @@ SQLTypeAdapter::assign(const null_type&)
 }
 
 char
+#if __cplusplus < 201703L
+SQLTypeAdapter::at(size_type i) const throw(std::out_of_range)
+#else
 SQLTypeAdapter::at(size_type i) const noexcept(false)
+#endif
 {
        if (buffer_) {
                if (i <= length()) {
diff --git a/mysql++-3.2.3/lib/stadapter.h b/mysql++-3.2.3/lib/stadapter.h
index 2343d69..d7b8f48 100644
--- a/mysql++-3.2.3/lib/stadapter.h
+++ b/mysql++-3.2.3/lib/stadapter.h
@@ -221,7 +221,11 @@ public:
        /// WARNING: The throw-spec is incorrect, but it can't be changed
        /// until v4, where we can break the ABI.  Throw-specs shouldn't be
        /// relied on anyway.
+#if __cplusplus < 201703L
+       char at(size_type i) const throw(std::out_of_range);
+#else
        char at(size_type i) const noexcept(false);
+#endif
 
        /// \brief Compare the internal buffer to the given string
        ///

tangent added on 2018-07-12 19:50:09:
Fixed by [799b4851e5ab].