Hi, I am writing C++ functions that are to be called via .Call() interface. I'd been using error() (from R.h) to return to R if there is an error, but then I realized that this might be not safe as supposedly error() doesn't throw an exception and therefore some destructors do not get called and some memory may leak. Here is a simple example extern "C" void foo() { string str = "hello"; error("message"); } The memory allocated for str is leaked. Did anyone think about this and find a way to work around the problem? Thanks, Vadim [[alternative HTML version deleted]]
I am sending this reply on behalf of Erik (who is not a member of this list). - Lennart -----Original Message----- From: K?llen, Erik Sent: 9 mars 2004 11:37 To: Borgman, Lennart Subject: RE: [R] error() and C++ destructors I would do something like: class error_exception { public: error_exception(const string &str) : msg(str) {} string msg; }; void my_error(const string &str) { throw error_exception(str); } int real_my_method(int a, char *b) { /* some code... */ return 0; } // this is the public method: int my_method(int a, char *b) { try { return real_my_method(a, b); } catch (error_exception &e) { error(e.msg); } } You could probably even create a macro like: #define R_METHOD_IMPL(rettype, name, paramlist) \ rettype real_##name paramlist; \ rettype name paramlist { \ try { \ return real_##name paramlist; \ } \ catch (error_exception &e) { \ error(e.msg); \ } \ } \ rettype real_##name paramlist You would use this macro like: R_METHOD_IMPL(int, my_method, (int a, char *b)) { // source code here } I think it would work, but I'm not sure (untested). /Erik K?ll?n -----Original Message----- From: Vadim Ogranovich [mailto:vograno at evafunds.com] Sent: 2 mars 2004 22:00 To: R Help List Subject: [R] error() and C++ destructors Hi, I am writing C++ functions that are to be called via .Call() interface. I'd been using error() (from R.h) to return to R if there is an error, but then I realized that this might be not safe as supposedly error() doesn't throw an exception and therefore some destructors do not get called and some memory may leak. Here is a simple example extern "C" void foo() { string str = "hello"; error("message"); } The memory allocated for str is leaked. Did anyone think about this and find a way to work around the problem? Thanks, Vadim [[alternative HTML version deleted]] ______________________________________________ R-help at stat.math.ethz.ch mailing list https://www.stat.math.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
And maybe I stressed Erik a bit, because he corrected himself some minutes later (when I was no longer looking over his shoulder). Again on behalf of Erik. - Lennart -----Original Message----- From: K?llen, Erik Sent: 9 mars 2004 13:40 To: Borgman, Lennart Subject: RE: [R] error() and C++ destructors Whoops. This code leaks memory for the exception. It would be better to throw a pointer: void my_error(const string &str) { throw new error_exception(str); } int my_method(int a, char *b) { try { return real_my_method(a, b); } catch (error_exception *pe) { static char error_msg[SOME_LARGE_NUMBER]; strncpy(error_msg, pe->msg.c_str(), sizeof(error_msg)); delete pe; error(error_msg); } } -----Original Message----- From: Borgman, Lennart Sent: 9 mars 2004 13:35 To: 'r-help at stat.math.ethz.ch' Subject: RE: [R] error() and C++ destructors I am sending this reply on behalf of Erik (who is not a member of this list). - Lennart -----Original Message----- From: K?llen, Erik Sent: 9 mars 2004 11:37 To: Borgman, Lennart Subject: RE: [R] error() and C++ destructors I would do something like: class error_exception { public: error_exception(const string &str) : msg(str) {} string msg; }; void my_error(const string &str) { throw error_exception(str); } int real_my_method(int a, char *b) { /* some code... */ return 0; } // this is the public method: int my_method(int a, char *b) { try { return real_my_method(a, b); } catch (error_exception &e) { error(e.msg); } } You could probably even create a macro like: #define R_METHOD_IMPL(rettype, name, paramlist) \ rettype real_##name paramlist; \ rettype name paramlist { \ try { \ return real_##name paramlist; \ } \ catch (error_exception &e) { \ error(e.msg); \ } \ } \ rettype real_##name paramlist You would use this macro like: R_METHOD_IMPL(int, my_method, (int a, char *b)) { // source code here } I think it would work, but I'm not sure (untested). /Erik K?ll?n -----Original Message----- From: Vadim Ogranovich [mailto:vograno at evafunds.com] Sent: 2 mars 2004 22:00 To: R Help List Subject: [R] error() and C++ destructors Hi, I am writing C++ functions that are to be called via .Call() interface. I'd been using error() (from R.h) to return to R if there is an error, but then I realized that this might be not safe as supposedly error() doesn't throw an exception and therefore some destructors do not get called and some memory may leak. Here is a simple example extern "C" void foo() { string str = "hello"; error("message"); } The memory allocated for str is leaked. Did anyone think about this and find a way to work around the problem? Thanks, Vadim [[alternative HTML version deleted]] ______________________________________________ R-help at stat.math.ethz.ch mailing list https://www.stat.math.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
One shortcoming of Erik's solution is that it can only catch the exceptions of type error_exception. For example it won't work if my code calls some third party library that can throw exceptions of some other types. In case it's of interest to someone here is the boilerplate that I ended up using (note the similarity between my errMsg and error_message from Erik's solution): extern "C" SEXP foo(SEXP x) { int hasFailed=0; char errMsg[2048]; // NO C++ objects above this line try { // do the work ... } cach (std::exception e) { hasFailed = 1; strncopy(errMsg, e.what(), sizeof(errMsg)); } catch (OtherException e) { hasFailed = 1; ... } // NO C++ objects below this line if (hasFailed) { error(errMsg); } return x; } One thing I don't like about my solution is that I need to remember to set hasFailed in each and every catch block (and "I often remember to forget these sort of things" :-)> -----Original Message----- > From: Lennart.Borgman at astrazeneca.com > [mailto:Lennart.Borgman at astrazeneca.com] > Sent: Tuesday, March 09, 2004 4:59 AM > To: r-help at stat.math.ethz.ch > Subject: RE: [R] error() and C++ destructors > > > And maybe I stressed Erik a bit, because he corrected himself > some minutes later (when I was no longer looking over his > shoulder). Again on behalf of Erik. > > - Lennart > > > -----Original Message----- > From: K?llen, Erik > Sent: 9 mars 2004 13:40 > To: Borgman, Lennart > Subject: RE: [R] error() and C++ destructors > > > Whoops. > > This code leaks memory for the exception. > It would be better to throw a pointer: > > void my_error(const string &str) { > throw new error_exception(str); > } > > int my_method(int a, char *b) { > try { > return real_my_method(a, b); > } > catch (error_exception *pe) { > static char error_msg[SOME_LARGE_NUMBER]; > strncpy(error_msg, pe->msg.c_str(), sizeof(error_msg)); > delete pe; > error(error_msg); > } > } > > -----Original Message----- > From: Borgman, Lennart > Sent: 9 mars 2004 13:35 > To: 'r-help at stat.math.ethz.ch' > Subject: RE: [R] error() and C++ destructors > > > I am sending this reply on behalf of Erik (who is not a > member of this list). > > - Lennart > > > -----Original Message----- > From: K?llen, Erik > Sent: 9 mars 2004 11:37 > To: Borgman, Lennart > Subject: RE: [R] error() and C++ destructors > > > I would do something like: > > class error_exception { > public: > error_exception(const string &str) : msg(str) {} > string msg; > }; > > void my_error(const string &str) { > throw error_exception(str); > } > > int real_my_method(int a, char *b) { > /* > some code... > */ > return 0; > } > > // this is the public method: > int my_method(int a, char *b) { > try { > return real_my_method(a, b); > } > catch (error_exception &e) { > error(e.msg); > } > } > > You could probably even create a macro like: > #define R_METHOD_IMPL(rettype, name, paramlist) \ > rettype real_##name paramlist; \ > rettype name paramlist { \ > try { \ > return real_##name paramlist; \ > } \ > catch (error_exception &e) { \ > error(e.msg); \ > } \ > } \ > rettype real_##name paramlist > > > You would use this macro like: > R_METHOD_IMPL(int, my_method, (int a, char *b)) { > // source code here > } > > I think it would work, but I'm not sure (untested). > > > /Erik K?ll?n > > > -----Original Message----- > From: Vadim Ogranovich [mailto:vograno at evafunds.com] > Sent: 2 mars 2004 22:00 > To: R Help List > Subject: [R] error() and C++ destructors > > > Hi, > > I am writing C++ functions that are to be called via .Call() > interface. I'd been using error() (from R.h) to return to R > if there is an error, but then I realized that this might be > not safe as supposedly error() doesn't throw an exception and > therefore some destructors do not get called and some memory > may leak. Here is a simple example > > extern "C" void foo() { > string str = "hello"; > error("message"); > } > > The memory allocated for str is leaked. > > Did anyone think about this and find a way to work around the problem? > > Thanks, > Vadim > > [[alternative HTML version deleted]] > > ______________________________________________ > R-help at stat.math.ethz.ch mailing list > https://www.stat.math.ethz.ch/mailman/listinfo> /r-help > PLEASE > do read the posting guide! > http://www.R-project.org/posting-guide.html > > ______________________________________________ > R-help at stat.math.ethz.ch mailing list > https://www.stat.math.ethz.ch/mailman/listinfo> /r-help > PLEASE > do read the posting guide! > http://www.R-project.org/posting-guide.html >