How to append to the what string of std::runtime_error - c++

In the C++ library I'm writing I've extended std::runtime_error (just to have a unique type -- I don't need anything beyond a what-string). But I sometimes want to catch the exception at the user entry point to append additional context information to the what string, and then rethrow it. But there does not appear to be anyway to modify the what string of runtime_error. Why is it designed that way? Is it to avoid possible out-of-memory condition during the realloc of the internal string buffer (which would lead to a new exception)? Or do they just want to encourage the use of nested exceptions to do this kind of thing? (Nested exceptions seems unnecessarily cumbersome since it's all within the context of one library, but maybe I'm being wrong-headed.) My current approach is to override the virtual what method and return my own (appendable) string:
#include <stdexcept>
#include <string>
class MyException : public std::runtime_error
{
public:
explicit MyException(const std::string& what_arg) :
MyException(what_arg.data())
{
}
explicit MyException(const char* what_arg) :
runtime_error(""),
what_("MyException: ")
{
append(what_arg);
}
const char* what() const noexcept
{
return what_.data();
}
void append(const char* msg)
{
what_.append(msg);
}
void append(const std::string& msg)
{
what_.append(msg);
}
private:
// As near as I can tell, there is no way to modify the what arg
// of runtime_error, so I don't use it and make make my own what
// arg here.
//
std::string what_;
};
So is this approach evil? Is there a better way?

Related

how to throw an exception when there is no constructor in the inherited class?

I'm not sure the question is appropriate but I'll try my best.
This is my homework problem.
The homework ask me to throw an exception if two lines are parallel or equal.
The original codes are provided by my professor and my job is to modify it to make it able to throw an exception.
line.h
class RuntimeException{
private:
string errorMsg;
public:
RuntimeException(const string& err) { errorMsg = err; }
string getMessage() const { return errorMsg; }
};
class EqualLines: public RuntimeException{
public:
//empty
};
class ParallelLines: public RuntimeException{
public:
//empty
};
class Line{
public:
Line(double slope, double y_intercept): a(slope), b(y_intercept) {};
double intersect(const Line L) const throw(ParallelLines,
EqualLines);
//...getter and setter
private:
double a;
double b;
};
Professor told us NOT to modify the header file, only the .cpp file can be modifed.
line.cpp
double Line::intersect(const Line L) const throw(ParallelLines,
EqualLines){
//below is my own code
if ((getSlope() == L.getSlope()) && (getIntercept() != L.getIntercept())) {
//then it is parallel, throw an exception
}
else if ((getSlope() == L.getSlope()) && (getIntercept() == L.getIntercept())) {
//then it is equal, throw an exception
}
else {
//return x coordinate of that point
return ((L.getIntercept()-getIntercept()) / (getSlope()-L.getSlope()));
}
//above is my own code
}
since those two inherited classes are empty hence no constructor to initialize the errorMsg , nor I can create an object of those classes to throw exception. Any alternate solution to achieve this?
Because you have an exception specifier, you may only throw EqualLines or ParallelLines. These exception types have no default constructor (their base type's doesn't have a default constructor) and have no other constructors. The only way to construct either of these exceptions is to copy an existing one. It's impossible to throw either of those exceptions without modifying the headers or violating the standard. I would consult with the professor, it looks like a mistake to me.
In general, exception specifiers are a bad idea. See this answer. They are in fact deprecated.

C++ invalid object return semantics

Couldn't find the answer in any similar-named question.
I want a user to be able to initialize a string member at any point in the lifetime of an object, not necessarily on construction, but I want them to know that the object is invalid until the string is initialized...
When creating a simple class, say the following:
#include <string>
class my_class {
public:
my_class() : _my_str() { }
my_class(const std::string & str) : my_class() {
set_my_str(str);
}
std::string get_my_str() const {
return _my_str;
}
void set_my_str(const std::string & str) {
_my_str = str;
}
private:
std::string _my_str;
};
and a user creates an empty instance of the class (i.e. using the empty constructor), _my_str will be an empty/uninitialized string?
So, I see two ways of handling behavior: the way mentioned above, where an empty string is returned, or a possible second way:
#include <string>
class my_class {
public:
my_class() : _my_str(), _my_str_ptr(nullptr) { }
my_class(const std::string & str) : my_class() {
set_my_str(str);
}
std::string * get_my_str() const {
return _my_str_ptr;
}
void set_my_str(const std::string & str) {
_my_str = str;
_my_str_ptr = &_my_str;
}
private:
std::string _my_str;
std::string * _my_str_ptr;
};
Where you return a nullptr, and you maintain a pointer to a local variable?
Is that valid behavior? Which way is preferred and why? Wouldn't the second way be better since you are telling the user, "listen, this object is currently invalid, you need to initialize it" while still implying that you are managing the lifetime of such object.
_my_str will be an empty/uninitialized string?
Empty, yes. Uninitialized, no. It's completely initialized (to an empty string).
Where you return a nullptr, and you maintain a pointer to a local variable?
Is that valid behavior?
Yes it's valid, but
Which way is preferred and why? Wouldn't the second way be better since you are telling the user, "listen, this object is currently invalid, you need to initialize it" while still implying that you are managing the lifetime of such object.
It makes absolutely no sense to maintain two distinct member variables for this. It sounds like what you need is std::optional (or the equivalent in Boost, boost::optional), so that _my_str has two states: empty/invalid (contains no string) and non-empty/valid (contains a string):
#include <string>
#include <experimental/optional>
using std::experimental::optional;
class my_class {
public:
my_class() /* default-initializes _my_str as empty */ { }
my_class(const std::string & str) : _my_str(str) { }
const std::string * get_my_str() const {
if (_my_str) // if it exists
return &*_my_str; // return the string inside the optional
else
return nullptr; // if the optional is empty, return null
}
/* Or simply this, if you don't mind exposing a bit of the
implementation details of the class:
const optional<std::string> & get_my_str() const {
return _my_str;
}
*/
void set_my_str(const std::string & str) {
_my_str = str;
}
private:
optional<std::string> _my_str;
};
If "" (an empty string) can be used as a sentinel value to signify the "empty/invalid" state in your case, then you can just do this:
#include <string>
class my_class {
public:
my_class() /* default-initializes _my_str as "" */ { }
my_class(const std::string & str) : _my_str(str) { }
const std::string * get_my_str() const {
if (!_my_str.empty()) // if it'a non-empty
return &_my_str; // return the non-empty string
else
return nullptr; // if it's empty, return null
}
void set_my_str(const std::string & str) {
_my_str = str;
}
private:
std::string _my_str;
};
In general, the pattern you're referring to is called Null object pattern.
The "oldest way" of implementing it was using one of possible values of a variable and reserving it for "no value" meaning. In case of a string an empty string commonly was used in such a way. Obviously not always possible, when all values were needed.
The "old way", was always using a pointer - (const T* get_t() const). This way the whole range of variable values could be meaningful, and still "no value" semantics were available by means of returning a null pointer. This was better, but still pointers are not as comfortable to use, not safe. Nowadays, pointers are usually bad engineering.
The modern way is optional<T> (or boost::optional<T>).
An empty std::string value is not per definition invalid. It is just empty.
On important difference is that the second "get_..." approach does not copy the object but gives the user a non const pointer to the internal string which leads to violation of const correctness since you imply that the class may not be changed by having const at the get method while still providing a pointer that may change the internal state.
If your logic implies that "empty string" == "invalid" and if this is a possible state there is not much of a difference whether the user must do
if (get_my_str())) // use valid pointer to nonempty string versus
if(!get_my_str().empty()) // use valid nonempty string
I think.
You'd want to return std::string const & from your get method and leave it to the user wether to copy the object or not.
4.1. No forced copy (versus by value return std::string)
4.2. No pointer which may be nullptr and accidentally dereferenced.
4.3. Passing around and storing a pointer which may outlive the object is more common that dangling references.
I want a user to be able to initialize the string later on, not necessarily on construction, but I want them to be able to know that the object is invalid until the string is initialized...
The question is: Is an empty string actually a "valid" value after proper initialization?
If yes: use optional to add one additional state signaling validity.
If no: let the emptyness of the string stand for invalidity of your object.

C++ exceptions - what isn't acting as it should

I've been bragging a friend of mine about C++ (scopes and RAII and static typing ftw) (I'd be embarrassed if this were me and not ask :P) but as I'm looking at it I am puzzled as tp what is going wrong. I hope you guys can help. She's coming from Java hence the CamcelCase
ListIndexOutOfBoundsException.h
#ifndef LISTINDEXOUTOFBOUNDSEXCEPTION_H_
#define LISTINDEXOUTOFBOUNDSEXCEPTION_H_
#include <exception>
namespace Structures {
class ListIndexOutOfBoundsException: public ::std::exception {
public:
ListIndexOutOfBoundsException(int index, int length);
virtual const char* what() const noexcept;
virtual ~ListIndexOutOfBoundsException() noexcept;
private:
const char* errorString;
};
}
#endif /* LISTINDEXOUTOFBOUNDSEXCEPTION_H_ */
ListIndexOutOfBoundsException.cpp
#include "ListIndexOutOfBoundsException.h"
#include <string>
#include <sstream>
namespace Structures {
using ::std::stringstream;
ListIndexOutOfBoundsException::ListIndexOutOfBoundsException(int index,int length) {
stringstream errorText("List index (");
errorText<<index<<") out of bounds! (list length: "<<length<<")";
errorString = errorText.str().c_str();
}
const char* ListIndexOutOfBoundsException::what() const noexcept {
return errorString;
}
ListIndexOutOfBoundsException::~ListIndexOutOfBoundsException() noexcept {
delete errorString;
}
}
When thrown this happens:
terminate called after throwing an instance of
'Structures::ListIndexOutOfBoundsException'
what(): OfBoundsException
I cannot work out where "OfBoundsException" has come from. What is going on!?
When the constructor goes out of scope, errorText no longer points to valid data, so all bets are off when you call what() (it invokes undefined behavior). The easiest fix is to derive from std::runtime_error, as that keeps a std::string (or equivalent) which is valid for the lifetime of the exception.
The problem is this
errorString = errorText.str().c_str();
errorText was a local object to the constructor that went out of scope and freed the memory it was using for it's c_str().
Try replacing errorString with a char errorString[SomeLimit]; and using basic string operations to write to it. Using a stringstream is somewhat overly complex for an exceptionhandler.

What should the return type be when the function might not have a value to return?

In the old days, you might have a function like this:
const char* find_response(const char* const id) const;
If the item could not be found, then a null could be returned to indicate the fact, otherwise obviously return the relevant string.
But when the function is changed to:
const std::string& find_response(const std::string& id) const;
What do you return to indicate item not found?
Or should signature really be:
bool find_response(const std::string& id, std::string& value) const;
What would be the most elegant modern C++ way?
boost::optional. It was specifically designed for this kind of situation.
Note, it will be included in upcoming C++14 standard as std::optional. Update: After reviewing national body comments to N3690, std::optional was voted out from C++14 working paper into a separate Technical Specification. It is not a part of the draft C++14 as of n3797.
Compared to std::unique_ptr, it avoids dynamic memory allocation, and expresses more clearly its purpose. std::unique_ptr is better for polymorphism (e.g. factory methods) and storing values in containers, however.
Usage example:
#include <string>
#include <boost/none.hpp>
#include <boost/optional.hpp>
class A
{
private:
std::string value;
public:
A(std::string s) : value(s) {}
boost::optional<std::string> find_response(const std::string& id) const
{
if(id == value)
return std::string("Found it!");
else
return boost::none;
//or
//return boost::make_optional(id == value, std::string("Found it!"));
}
//You can use boost::optional with references,
//but I'm unfamiliar with possible applications of this.
boost::optional<const std::string&> get_id() const
{
return value;
}
};
#include <iostream>
int main()
{
A a("42");
boost::optional<std::string> response = a.find_response("42"); //auto is handy
if(response)
{
std::cout << *response;
}
}
What would be the most elegant modern C++ way?
There's, as always, not just one solution to this problem.
If you decide to go for any solution that references the original resonse instance, you're on a slippery road when it comes to aliasing and memory management, especially in a multi threaded environment. By copying the response to the caller, no such issues arises.
Today, I would do this:
std::unique_ptr<std::string> find_response(const std::string& id) const;
That way, you can check for nullptr as "in the olden days" and it's 100% clear who's responsibility it is to clear up the returned instance: the caller.
The only downside I see of this, is the additional copy of the response string, but don't dismiss that as a downside until measured and proven so.
Another way is to do as is done when searching std::set<> and std::map<> - return a std::pair<bool, const char*> where one value is bool is_found and the other is const char* response. That way you don't get the "overhead" of the additional response copy, only of the returned std::pair<> which is likely to be maximally optimized by the compiler.
If the function is returning a string by reference, but needs the ability to indicate that no such string exists, the most obvious solution is to return a pointer, which is basically a reference that can be null, i.e. exactly what was sought after.
const std::string* find_response(const std::string& id) const;
There are several good solutions here already. But for the sake of completeness I'd like to add this one. If you don't want to rely on boost::optional you may easily implement your own class like
class SearchResult
{
SearchResult(std::string stringFound, bool isValid = true)
: m_stringFound(stringFound),
m_isResultValid(isValid)
{ }
const std::string &getString() const { return m_stringFound; }
bool isValid() const { return m_isResultValid; }
private:
std::string m_stringFound;
bool m_isResultValid;
};
Obviously your method signature looks like this then
const SearchResult& find_response(const std::string& id) const;
But basically that's the same as the boost solution.
Use of pointers in C++ is forgiven if you need to return a nullable entity. This is widely accepted.
But of course bool find_response(const std::string& id, std::string& value) const; is quite verbose. So it is a matter of your choice.
I think the second way is better. Or you can write like this:
int find_response(const std::string& id, std::string& value) const;
if this function return -1, it tells that you don't find the response.

How can I prevent the need to copy strings passed to a avr-gcc C++ constructor?

In the ArduinoUnit unit testing library I have provided a mechanism for giving a TestSuite a name. A user of the library can write the following:
TestSuite suite("my test suite");
// ...
suite.run(); // Suite name is used here
This is the expected usage - the name of the TestSuite is a string literal. However to prevent hard-to-find bugs I feel obliged to cater for different usages, for example:
char* name = (char*) malloc(14);
strcpy(name, "my test suite");
TestSuite suite(name);
free(name);
// ...
suite.run(); // Suite name is used here
As such I have implemented TestSuite like this:
class TestSuite {
public:
TestSuite(const char* name) {
name_ = (char*) malloc(strlen(name) + 1);
strcpy(name_, name);
}
~TestSuite() {
free(name_);
}
private:
char* name_;
};
Putting aside the issue of failing to deal with memory allocation failures in the constructor I'd prefer to simply allocate the pointer to a member variable like this:
class TestSuite {
public:
TestSuite(const char* name) : name_(name) {
}
private:
const char* name_;
};
Is there any way I can change the interface to force it to be used 'correctly' so that I can do away with the dynamic memory allocation?
What if you provide two overloaded constructors?
TestSuite(const char* name) ...
TestSuite(char* name) ...
If called with a const char*, then the constructor could make a copy of the pointer, assuming that the string will not go away. If called with a char*, the constructor could make a copy of the whole string.
Note that it is still possible to subvert this mechanism by passing a const char* to the constructor when the name is in fact dynamically allocated. However, this may be sufficient for your purposes.
I should note that I have never actually seen this technique used in an API, it was just a thought that occurred to me as I was reading your question.
Documentation. For example,
/**
* Test suite constructor.
* #param name test suite name cstring, shared
*/
TestSuite(char const *name) {
// ...
A shared pointer implies that the pointed object must be alive during the lifetime of this object.
Well, you can use a std::string that will take care of all memory allocation
class TestSuite {
public:
TestSuite(const std::string &name):name_(name) {
}
~TestSuite() {
}
private:
std::string name_;
};
Edit :
If it is the call to malloc() that you want to avoid you could do this :
class TestSuite {
public:
TestSuite(const char *name){
memcpy(name_, name, min(16, strlen(name));
}
private:
char name_[16];
};
This will waste some memory however, which can be an issue on embedded platforms.
Have a char name[XYZ] member of your TestSuite (with an XYZ large enough to comfortably display the name) and use strncpy to copy the string (with a maximum length of XYZ-1).
Why are you using char* and malloc when you have the nice C++ string class which can takes a string literal or a char* in its constructor ?
Are you able to use std::string? You could have it as std::string name_ and have the STL take care of the memory allocation for you..
class TestSuite {
public:
TestSuite(const char* name) : name_(name) {}
~TestSuite() {}
private:
std::string name_;
};
Don't forget to include <string>.
Reference