matherror issue
-
Hi, Qts!
Before QtCreator I used _matherr function to detect math errors . When I did it in QtCreator (for windows) I've got a swear. What to do and maybe there are more modern ways to detect math errs now? For instance when they get the square root from a negative number etc.#include "mainwindow.h" #include "ui_mainwindow.h" #include <math.h> int err_counter = 0; //QtCreator says: //mainwindow.cpp:7:5: warning: '_matherr' redeclared without 'dllimport' attribute: previous 'dllimport' ignored //math.h:286:23: note: previous declaration is here //math.h:286:3: note: previous attribute is here //_mingw.h:61:40: note: expanded from macro '_CRTIMP' int _matherr (struct _exception *a) { err_counter++; } MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_bt_test1_clicked() { double x = -10.0; double res = sqrt(x); //tst calc1 res = x / 0.0; //tst calc2 if(err_counter == 0) ui->statusbar->showMessage("OK, no errs"); else ui->statusbar->showMessage("Some errs' happened (" + QString::number(err_counter) + ")"); }
-
@qAlexKo said in matherror issue:
//QtCreator says:
Do you mean QtCreator code model in the editor or compiler?
So, does your application compile?
Also, what compiler do you use? -
@jsulm said in matherror issue:
Do you mean QtCreator code model in the editor or compiler?
So, does your application compile?
Also, what compiler do you use?I've got this error in the QtCreator editor. I can't compile my app
My compiler is minGW 7.3.0 64-bitCompiler says "Multiple definition of _matherr"
-
On Linux I don't have problems compiling your code.
Don't have Windows at hand to test. -
-
I would guess you have to find another way to catch those errors as the MinGW runtime catches this by itself and writes to stderr: https://github.com/mingw-w64/mingw-w64/blob/master/mingw-w64-crt/crt/merr.c
You can use the MSVC compiler instead for instance.
-
@Christian-Ehrlicher said in matherror issue:
I would guess you have to find another way to catch those errors as the MinGW runtime catches this by itself and writes to stderr: https://github.com/mingw-w64/mingw-w64/blob/master/mingw-w64-crt/crt/merr.c
You can use the MSVC compiler instead for instance.
Thanx, indeed I need just an indicator for math errors happened in the calculation block. The example you've just given also containes _matherr in question.
I've found out another way to indicate math errors in a calculaton block:int err_indicator = 0; //global indicator void MainWindow::on_bt_test1_clicked() { errno = 0; double res = 0; res = sqrt(-10.0); //tst err calc1 res = 10.0 / 0.0; //tst err calc2 res = 10.0 / 1.0; //tst OK calc3 res = sqrt(10.0); //tst OK calc4 if(!errno) { err_indicator=0; ui->statusbar->showMessage("OK, no errs"); } else { err_indicator=1; ui->statusbar->showMessage("Some err(s)' happened"); } }
So I think I'll do like this, to save my time thinking of why _matherr is not perfect for windows Qtcreator.
-
@qAlexKo
I am jumping in here. I do not use Windows or MinGW. I cannot test anything, but I had a look at https://github.com/Alexpux/mingw-w64/blob/master/mingw-w64-crt/crt/merr.c which I take to be the source for MinGW's_matherr
stuff.There it defines
int __CRTDECL _matherr (struct _exception *pexcept)
which is the handling function which hard-codes callingfprintf(stderr
that you do not want.I don't think you are supposed to redefine function named
_matherr()
. Rather I seetypedef int (__cdecl *fUserMathErr)(struct _exception *); static fUserMathErr stUserMathErr; void __mingw_setusermatherr (int (__cdecl *f)(struct _exception *)) { stUserMathErr = f; __setusermatherr (f); }
I assume MinGW start up code calls
__mingw_setusermatherr(_matherr);
? So, can you not replace their_matherr()
as handler by writing your own under a different name and calling__mingw_setusermatherr(your_matherr)
? For your function copy their_matherr(struct _exception *pexcept)
for theswitch
statement and just replace the finalfprintf
with whatever you want instead?This is all of course if you want that old behaviour, rather than being happy with
errno
. -
@JonB said in matherror issue:
This is all of course if you want that old behaviour, rather than being happy with errno.
Yes, your way is working OK:
#include "mainwindow.h" #include "ui_mainwindow.h" #include <math.h> #include <string> using namespace std; typedef int (__cdecl *fUserMathErr)(struct _exception *); static fUserMathErr stUserMathErr; //-------------------------------- string math_err_res; int __CRTDECL _matherr_my (struct _exception *pexcept) { const char * type; switch(pexcept->type) { case _DOMAIN: type = "Argument domain error (DOMAIN)"; break; case _SING: type = "Argument singularity (SIGN)"; break; case _OVERFLOW: type = "Overflow range error (OVERFLOW)"; break; case _PLOSS: type = "Partial loss of significance (PLOSS)"; break; case _TLOSS: type = "Total loss of significance (TLOSS)"; break; case _UNDERFLOW: type = "The result is too small to be represented (UNDERFLOW)"; break; default: type = "Unknown error"; break; } char buf[200]; sprintf (buf, "_matherr(): %s in %s(%g, %g) (retval=%g)\n", type, pexcept->name, pexcept->arg1, pexcept->arg2, pexcept->retval); math_err_res = type; return 0; } MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); __mingw_setusermatherr(_matherr_my); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_bt_test1_2_clicked() { double res = 0; res = sqrt(-10.0); //tst err calc1 res = 10.0 / 0.0; //tst err calc2 res = 10.0 / 1.0; //tst OK calc3 res = sqrt(10.0); //tst OK calc4 if(math_err_res.size() == 0) ui->statusbar->showMessage("OK, no errs"); else { err_indicator=1; ui->statusbar->showMessage("Some err(s)' happened (" + QString(math_err_res.c_str()) + ")"); } math_err_res = ""; }
However I doubt - the source text will not be for all compilers? - I have a different compiler for my app Linux version.
-
@qAlexKo said in matherror issue:
for windows Qtcreator
I don't understand what this has to do with windows nor QtCreator... It's an issue of the compiler you use...
-
@qAlexKo said in matherror issue:
However I doubt - the source text will not be for all compilers? - I have a different compiler for my app Linux version.
The code in itself is pretty standard.
- If you are on Linux you will want to get rid of
__CRTDECL
I think. - But I think then you will not be using MinGW, and if this code is only supposed to work under that you will put your
__mingw_setusermatherr(_matherr_my);
statement (plus the whole of theint _matherr_my (struct _exception *pexcept)
function) inside some#if
/#ifdef
which tests for a defined symbol indicating it is being compiled under MinGW.
- If you are on Linux you will want to get rid of
-
-
-
@jsulm said in matherror issue:
On Linux I don't have problems compiling your code.
Don't have Windows at hand to test.Sorry I am again! :) I am in Linux Qtcreatornow.
I said that there is no problem with _matherror in Linux Clang compiler but unexpectedly I've got one! ;) Look:
if you compile with the commented lines the compilation will be OK.
But If you remove the comments to use pexcept pointer -- QtCreator says about an error in line where "pexcept->type"
"mainwindow.cpp:14:17: error: member access into incomplete type 'struct _exception'
mainwindow.cpp:11:22: note: forward declaration of '_exception'"
#include <exception> has not helped
what else should I include?#include "mainwindow.h" #include "ui_mainwindow.h" #include <exception> #include <math.h> #include <string> using namespace std; //-------------------------------- string math_err_res; int _matherr (struct _exception *pexcept) { const char * type=NULL; // switch(pexcept->type) // { // case _DOMAIN: // type = "Argument domain error (DOMAIN)"; // break; // } // char buf[200]; // sprintf (buf, "_matherr(): %s in %s(%g, %g) (retval=%g)\n", // type, pexcept->name, pexcept->arg1, pexcept->arg2, pexcept->retval); math_err_res = type; return 0; } MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_bt_test1_2_clicked() { double res = 0; res = sqrt(-10.0); //tst err calc1 res = 10.0 / 0.0; //tst err calc2 res = 10.0 / 1.0; //tst OK calc3 res = sqrt(10.0); //tst OK calc4 if(math_err_res.size() == 0) ui->statusbar->showMessage("OK, no errs"); else { ui->statusbar->showMessage("Some err(s)' happened (" + QString(math_err_res.c_str()) + ")"); } math_err_res = ""; }
I have switched the Qtcreator compiler to gcc and the problem remained.
-
@qAlexKo said in matherror issue:
int _matherr (struct _exception *pexcept)
Shouldn't it be exception instead of _exception?
-
@JonB said in matherror issue:
If the int _matherr (struct _exception *pexcept) appears in merr.c you need to trace from there to find out where it (_exception) is defined. Maybe it's a MinGW-only definition/file, I don't know.
If I compile in Clang
int err_ind = 0; int _matherr (struct _exception *pexcept) { err_ind = 1; }
Compilation OK, but math exception doesn't work