matherror issue
-
wrote on 22 May 2024, 06:39 last edited by
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) + ")"); }
-
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? -
@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?wrote on 22 May 2024, 06:53 last edited by qAlexKo@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. -
wrote on 22 May 2024, 07:03 last edited by qAlexKo
@jsulm said in matherror issue:
On Linux I don't have problems compiling your code.
Don't have Windows at hand to test.Yes, I also have no problem in Linux Qtcreator. I need to transfer one my app to Windows.
-
-
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.
-
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.
wrote on 22 May 2024, 07:52 last edited by qAlexKo@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.
-
@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.
wrote on 22 May 2024, 08:10 last edited by JonB@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
. -
@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
.wrote on 22 May 2024, 09:05 last edited by qAlexKo@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.
-
@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 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...
-
@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.
wrote on 22 May 2024, 09:18 last edited by@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
-
-
-
wrote on 22 May 2024, 13:20 last edited by qAlexKo
@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.
-
@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?
-
@qAlexKo said in matherror issue:
int _matherr (struct _exception *pexcept)
Shouldn't it be exception instead of _exception?
wrote on 22 May 2024, 13:56 last edited by@jsulm said in matherror issue:
Shouldn't it be exception instead of _exception?
If I change to exception I am get this message
mainwindow.cpp:14:19: error: no member named 'type' in 'std::exception' -
@jsulm said in matherror issue:
Shouldn't it be exception instead of _exception?
If I change to exception I am get this message
mainwindow.cpp:14:19: error: no member named 'type' in 'std::exception' -
@qAlexKo
If theint _matherr (struct _exception *pexcept)
appears inmerr.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.wrote on 23 May 2024, 08:04 last edited by qAlexKo@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
1/17