PDA

View Full Version : Boost-like exceptions



PierreA
30th October 2017, 02:20
My program, so far, has been throwing ints as errors. I made it pop up a message if it failed to make a TIN, so I need to change this. The Boost exception class has a way of adding info to an exception as it is thrown up the call stack. For instance, a CSV line-parsing routine can throw an exception if a line has an odd number of quotation marks, and the next function up can add the filename to the exception. The Qt exception class doesn't do any such thing. Can it be added to Qt exception, or should I use the Boost exception?

high_flyer
30th October 2017, 22:16
Can it be added to Qt exception,
Qt is written in C++ so if you know what inheritance is, you should know it possible to add that functionality to QException.
More over the docs of QException state it in the very first sentence:

The QException class provides a base class for exceptions that can transferred across threads.

PierreA
31st October 2017, 11:10
I can pretty easily derive a class from QException that carries a payload, where the maximum payload size is known in advance (e.g. three ints and two pointers). I don't know how to stuff arbitrary-length strings into an exception without looking at how Boost does it. The problem is, if an out-of-memory occurs deep in the code, and somewhere up the stack a function tries to stuff a filename into the exception, that'll cause an out-of-memory exception while handling an out-of-memory exception, which is a no-no.

high_flyer
2nd November 2017, 11:16
I am sorry, but I don't follow.
What does your last post has to do with the first?
Anyway, if you use QString you don't have to worry about the length of the string.

PierreA
26th December 2017, 11:33
I was referring to the following sentence from the Boost site:

It supports transporting of arbitrary data to the catch site, which is otherwise tricky due to the no-throw requirements (15.5.1) for exception types.
Anyway, I'm trying to implement my exception type, looking at https://doc.qt.io/qt-5/qexception.html, and running into a problem. clone does new, which calls the copy constructor, but QException does not have a copy constructor! Do I just make my own, without calling QException's?

class BeziExcept: public QException
{
public:
BeziExcept(BeziExcept a);
BeziExcept(int num);
int exceptNumber;
int pointNumber[2];
void raise() const
{
throw *this;
}
BeziExcept *clone() const
{
return new BeziExcept(*this);
}
};

high_flyer
28th December 2017, 22:52
Now that I had a the possibility to read your second post with a bit more attention...

The problem is, if an out-of-memory occurs deep in the code, and somewhere up the stack a function tries to stuff a filename into the exception, that'll cause an out-of-memory exception while handling an out-of-memory exception, which is a no-no.
Well, I am not sure what you at all could you do in such a state since most things you would like to do would need memory.
Also, are you differentiating between stack and heap memory?
One way to deal with it is to allocate some memory at the start of the application (or before the usage of this exception), and hold it for your out of memory exception, and delete it just before you want to allocate your exception.
You could initialize a pre sized QByteArray as a placeholder for your string in your exception, so that you know your new exception will not be larger than the amount of memory you allocated as reserve.


clone does new, which calls the copy constructor, but QException does not have a copy constructor! Do I just make my own, without calling QException's?
well, if QException doesn't have one, you can't call it ;-)
And I'd say yes, I see no reason why you could not implement your own copy constructor.

ChrisW67
2nd January 2018, 08:01
As far as I can tell the QException class will have a default copy constructor. The implementation of QUnhandledException in the standard library does exactly what the docs describe.

Your BeziExcept code declares a conversion constructor (roughly looks like a copy constructor but does not have the requisite signature) but does not provide an implementation. Is that the error you see? Since the members are all basic types you could probably just omit line 4 altogether and rely on the default copy constructor, or you could implement it explicitly:


#include <QtCore>
#include <QDebug>

class BeziExcept: public QException {
public:
// default and conversion constructor
BeziExcept(int num = 0):
exceptNumber(num),
pointNumber{0, 0}
{
}
// Copy constructor
BeziExcept(const BeziExcept &a) {
exceptNumber = a.exceptNumber;
pointNumber[0] = a.pointNumber[0];
pointNumber[1] = a.pointNumber[1];
}
int exceptNumber;
int pointNumber[2];
void raise() const
{
throw *this;
}
BeziExcept *clone() const
{
return new BeziExcept(*this);
}
};


int main(int argc, char **argv) {
QCoreApplication app(argc, argv);

BeziExcept a(314);
qDebug() << "a" << a.exceptNumber;
BeziExcept b(a);
qDebug() << "b" << b.exceptNumber;
BeziExcept *c = b.clone();
qDebug() << "c" << c->exceptNumber;

return( 0 );
}