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
>