Hi,
Let me try to describe what kind of problem I have with mingw-w64,
because it becomes a nightmare for me, despite the fact that I have over
30 years of experience with C and c ++ compilers:
My ERP consists of a main program and two shared libraries.
On Linux, everything works as intended and it works flawlessly.
One of the shared libraries generates an exception, which until mingw64
gcc8 was always caught in the main program.
With mingw64 gcc9 and gcc10 this is no longer possible, so I have to
seek help to make my ERP work with new compilers as well.
To illustrate the problem I have prepared a test program that should
give a realistic picture of the problem.
Before I show the program itself, here are the results of several
variants, none of which are good(except linux).
***************************************************************************************************
linux //works as expected
-------------------------
Connecting to TRT-MRT ...
SQLException:Failed to connect to datasource: [unixODBC][Driver
Manager]Data source name not found and no default driver specified
sqlState=IM002 errorCode=0
#if __MINGW64__ && USECLASS == false //don't convert struct
odbc::SQLException to std::exception
------------------------------------------------------------------------------------------------
Connecting to TRT-MRT ...
runtime_error:Kuku lele --> THIS MUST NOT HAPPEN
catch blok passed--> THIS MUST NOT HAPPEN
TRT-MRT ! Hello, World! --> THIS MUST NOT HAPPEN
#if __MINGW64__ && USECLASS == true //convert struct odbc::SQLException
to std::exception
-----------------------------------------------------------------------------------------
Connecting to TRT-MRT ...
terminate called after throwing an instance of 'vkSQLException'
what(): Failed to connect to datasource: [unixODBC][Driver
Manager]Data source name not found and no default driver specified
#if __MINGW64__ && EXPTNTEST == true //using testdll_64.dll to throw
vkSQLException
-----------------------------------------------------------------------------------
Caught std::exception: Choke me! --> THIS IS FROM DLL
Connecting to TRT-MRT ...
Throwing vkSQLException. --> THIS IS FROM DLL
terminate called after throwing an instance of 'vkSQLException'
what(): Failed to connect to datasource: [unixODBC][Driver
Manager]Data source name not found and no default driver specified
***************************************************************************************************
And finally the test program:
-----------------------------
#include <odbc++/drivermanager.h>
#include <odbc++/connection.h>
#include <iostream>
#include <ostream>
#define USECLASS true //switch for using class exception
#define EXPTNTEST false //switch for using testdll_64.dll
#if __MINGW64__ && EXPTNTEST == true
#include <testdll.h>
#endif
#if __MINGW64__ && USECLASS == true && EXPTNTEST == false //convert
struct odbc::SQLException to std::exception
class vkSQLException : public std::exception {
odbc::SQLException e;
public:
vkSQLException(odbc::SQLException *e) {
this->e = *e;
}
const char* what() const throw() override {
return e.what();
}
int getErrorCode() const {
return e.getErrorCode();
}
const ODBCXX_STRING& getSQLState() const {
return e.getSQLState();
}
const ODBCXX_STRING& getMessage() const {
return e.getMessage();
}
};
#endif
#if __MINGW64__ && USECLASS == true && EXPTNTEST == true
static const void throwisppMainSQLException(odbc::SQLException *e)
noexcept(false) {
throw_vkSQLException(e);
}
#endif
#if __MINGW64__ && USECLASS == true && EXPTNTEST == false
static const void throwisppMainSQLException(odbc::SQLException *e)
noexcept(false) {
vkSQLException vke(e);
throw vke;
}
#endif
//-----------------------------------------------------------------------------------------------------------------------
int main( int argc, char *argv[] ) {
#if __MINGW64__ && EXPTNTEST == true
try {
throwException("Choke me!");
} catch (std::exception &e) {
fprintf(stdout, "Caught std::exception: %s\n", e.what());
} catch (...) {
fprintf(stdout, "Caught unknown exception.\n");
}
#endif
#if __MINGW64__ && USECLASS == true
odbc::isppMainSQLException = (void *)&throwisppMainSQLException;
#endif
try {
odbc::Connection *con;
std::cout << "Connecting to TRT-MRT ..." << std::endl << std::flush;
con = odbc::DriverManager::getConnection("TRT-MRT");
if (con)
;
throw std::runtime_error("Kuku lele\n");
} catch (odbc::SQLException & e) {
std::cout << std::endl << "SQLException:" << e.what() << "
sqlState=" << e.getSQLState() << " errorCode=" << e.getErrorCode() <<
std::endl;
} catch (std::runtime_error & e) {
std::cout << std::endl << "runtime_error:" << e.what() << std::endl;
}
#if __MINGW64__ && USECLASS == true
catch (vkSQLException & e) {
std::cerr << std::endl << "vkSQLException: Reason=" << e.what() <<
" sqlState=" << e.getSQLState() << " errorCode=" << e.getErrorCode() <<
std::endl;
}
#endif
catch (std::exception & e) {
std::cout << std::endl << "exception:" << e.what() << std::endl;
}
catch (...) {
std::exception_ptr e = std::current_exception();
std::cerr << std::endl << "??? ...:" << ((e) ?
e.__cxa_exception_type()->name() : " e == NULL") << std::endl;
try {
std::rethrow_exception(e);
} catch (std::exception & e) {
std::cerr << "Task failed exceptionally: " << e.what() << "\n";
}
}
std::cout << std::endl << "catch block passed" << std::endl;
try {
throw std::runtime_error("Hello, World!\n");
return 0;
} catch (const std::exception & e) {
std::cout << "TRT-MRT ! " << e.what() << std::endl;
}
return 0;
}
-----------------------------
Vladimir Koković, DP senior(70),
Serbia, Belgrade, 15.November 2020
_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public