[Rd] Grid pmax Unusual Result In Alpha Version
Hello, I find that the width of a plot is zero when three grobs are input but is as expected when any subset of two of the three grobs are used. -- Dario Strbenac University of Sydney Camperdown NSW 2050 Australia __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Grid pmax Unusual Result In Alpha Version
Sorry, I was dragging the laptop's cursor towards the Discard button but it activated on Send instead. Please ignore or delete from mailing archive. From: Martin Maechler Sent: Monday, 23 March 2020 11:10 PM To: Dario Strbenac Subject: Re: [Rd] Grid pmax Unusual Result In Alpha Version > Dario Strbenac > on Mon, 23 Mar 2020 10:19:46 + writes: > Hello, > I find that the width of a plot is zero when three grobs are input but is as expected when any subset of two of the three grobs are used. Please Dario, do send reproducible code with almost *EVERY* posting to R-devel ! > -- > Dario Strbenac > University of Sydney > Camperdown NSW 2050 > Australia > __ > R-devel@r-project.org mailing list > https://protect-au.mimecast.com/s/SBS7CwV1vMf0xJVOUVR_hV?domain=stat.ethz.ch __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
[Rd] Inconsistant result for normalizePath on Windows
Hi all, I saw a quite surprising result in the devel R when using the function *normalizePath*. If the input is a path to a folder, the function returns an absolute path with/without a slash at the end depending on the existence of the folder. I know both results are valid on Windows but this behavior is different than R3.6, I do not know if the change in the devel version is made on purpose. Here is a minimal example, suppose that the folder `C:/windows1/` does not exist. > normalizePath("C:/windows/", mustWork = FALSE) [1] "C:\\Windows" > normalizePath("C:/windows1/", mustWork = FALSE) [1] "C:\\windows1\\" In R 3.6, the return value always ends with a slash if the input ends with a slash. From the NEWS file, It seems like there are some changes to *normalizePath* but none of them should be relevant, it might be an unintentional result introduced by the update. Best, Jiefei [[alternative HTML version deleted]] __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Inconsistant result for normalizePath on Windows
Hi Jiefei, the change in handling trailing path separators is not on purpose, but is a byproduct of a new implementation of normalizePath, which now handles symbolic links and normalizes case in long path names. It is not documented what happens to trailing separators, and hence portable programs should not depend on it. I don't think it is a property that should be documented/specified. The behavior of normalizePath is way too complicated already and it's result is OS-specific anyway. In R-devel as well as in 3.6, the trailing separator is preserved when the path does not exist - simply, the original path is returned. When the path does exist, R-devel removes the trailing separator but R 3.6 does not, which is because the underlying Windows API call to implement it is now different. The new behavior reflects what GetFinalPathNameByHandle returns, which is a function now used for normalization also in other language runtimes on Windows. I think the new behavior is better: paths differing only in the trailing separator will be normalized to the same path. Best Tomas On 3/23/20 4:39 PM, Wang Jiefei wrote: Hi all, I saw a quite surprising result in the devel R when using the function *normalizePath*. If the input is a path to a folder, the function returns an absolute path with/without a slash at the end depending on the existence of the folder. I know both results are valid on Windows but this behavior is different than R3.6, I do not know if the change in the devel version is made on purpose. Here is a minimal example, suppose that the folder `C:/windows1/` does not exist. > normalizePath("C:/windows/", mustWork = FALSE) [1] "C:\\Windows" normalizePath("C:/windows1/", mustWork = FALSE) [1] "C:\\windows1\\" In R 3.6, the return value always ends with a slash if the input ends with a slash. From the NEWS file, It seems like there are some changes to *normalizePath* but none of them should be relevant, it might be an unintentional result introduced by the update. Best, Jiefei [[alternative HTML version deleted]] __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Inconsistant result for normalizePath on Windows
Re the trailing path separator - should file.path() be changed to not produce doubled path separators when an argument has a trailing path separator? Bill Dunlap TIBCO Software wdunlap tibco.com On Mon, Mar 23, 2020 at 9:24 AM Tomas Kalibera wrote: > > Hi Jiefei, > > the change in handling trailing path separators is not on purpose, but > is a byproduct of a new implementation of normalizePath, which now > handles symbolic links and normalizes case in long path names. It is not > documented what happens to trailing separators, and hence portable > programs should not depend on it. I don't think it is a property that > should be documented/specified. The behavior of normalizePath is way too > complicated already and it's result is OS-specific anyway. > > In R-devel as well as in 3.6, the trailing separator is preserved when > the path does not exist - simply, the original path is returned. When > the path does exist, R-devel removes the trailing separator but R 3.6 > does not, which is because the underlying Windows API call to implement > it is now different. The new behavior reflects what > GetFinalPathNameByHandle returns, which is a function now used for > normalization also in other language runtimes on Windows. I think the > new behavior is better: paths differing only in the trailing separator > will be normalized to the same path. > > Best > Tomas > > On 3/23/20 4:39 PM, Wang Jiefei wrote: > > Hi all, > > > > I saw a quite surprising result in the devel R when using the function > > *normalizePath*. If the input is a path to a folder, the function returns > > an absolute path with/without a slash at the end depending on the > existence > > of the folder. I know both results are valid on Windows but this behavior > > is different than R3.6, I do not know if the change in the devel version > is > > made on purpose. Here is a minimal example, suppose that the folder > > `C:/windows1/` does not exist. > > > >> normalizePath("C:/windows/", mustWork = FALSE) > > [1] "C:\\Windows" > >> normalizePath("C:/windows1/", mustWork = FALSE) > > [1] "C:\\windows1\\" > > > > > > In R 3.6, the return value always ends with a slash if the input ends > with > > a slash. From the NEWS file, It seems like there are some changes to > > *normalizePath* but none of them should be relevant, it might be an > > unintentional result introduced by the update. > > > > Best, > > Jiefei > > > > [[alternative HTML version deleted]] > > > > __ > > R-devel@r-project.org mailing list > > https://stat.ethz.ch/mailman/listinfo/r-devel > > __ > R-devel@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel > [[alternative HTML version deleted]] __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] unlink() on "~" removes the home directory
To clarify, these issues are about deleting the contents of the home directory, not the directory itself, which cannot be deleted by ordinary users on today's systems. Unfortunately this has to be fixed in the code that calls unlink(), such code must be aware of the expansions. The "R CMD build" case as you write has been fixed, if anyone finds any other instance of this problem in base R, please report, it will be fixed as well. The new argument "expand" has been added to unlink() to make these fixes easier. A variation on what you propose: tilde ("~") is now treated the same way as "." and ".." have already been by unlink(), which means it will never be considered for deletion (not even with expand=TRUE). There are still a number of ways to delete the contents of one's home directory, including tilde expansion with user name, with directory separators, etc. This special treatment of "~" will prevent only one pattern of the problem. One should always be careful when recursively/programmatically deleting files. Also, the new behavior can cause trouble in some cases when a file or directory named tilde exists, but hopefully not as bad as deleting the contents of user home directory. In principle, such file can still be deleted from R using a combination of tilde and wildcards with wildcard expansion enabled. Best Tomas On 2/26/20 11:47 PM, Gábor Csárdi wrote: !!! DON'T TRY THE CODE IN THIS EMAIL AT HOME !!! Well, unlink() does what it is supposed to do, so you could argue that there is nothing wrong with it. Also, nobody would call unlink() on "~", right? The situation is not so simple, however. E.g. if you happen to have a directory called "~", and you iterate over all files and directories to selectively remove some of them, then your code might end up calling unlink on the local "~" directory, and then your home is gone. But you would not create a directory named "~", that is just asking for trouble. Well, surely, _intentionally_ you would not do that. Unintentionally, you might. E.g. something like this is enough: # Create a subpath within a base directory badfun <- function(base = ".", path) { dir.create(file.path(base, path), recursive = TRUE, showWarnings = FALSE) } badfun(path = "~/foo") (If you did run this, be very careful how you remove the directory called "~"!) A real example is `R CMD build` which deletes the home directory of the current user if the root of the package contains a non-empty "~" directory. Luckily this is now fixed in R-devel, so R 4.0.0 will do better. (R 3.6.3 will not.) See https://github.com/wch/r-source/commit/1d4f7aa1dac427ea2213d1f7cd7b5c16e896af22 I have seen several bug reports about various packages (that call R CMD build) removing the home directory, so this indeed happens in practice to a number of people. The commit above will fix `R CMD build`, but it would be great to "fix" this in general. It seems pretty hard to prevent users from creating of a "~" directory. But preventing unlink() from deleting "~" does not actually seem too hard. If unlink() could just refuse removing "~" (when expand = TRUE), that would be great. It seems to me that the current behavior is very-very rarely intended, and its consequences are potentially disastrous. If unlink("~", recursive = TRUE) errors, you can still remove a local "~" file/dir with unlink("./~", ...). And you can still remove your home directory if you really want to do that, with unlink(path.expand("~"), ...). So no functionality is lost. Also, if anyone is aware of packages/functions that tend to create "~" directories or files, please let me know. I would be happy to submit a patch for the new unlink("~") behavior. Thanks, Gabor __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] unlink() on "~" removes the home directory
Thanks, I saw the commit, and it seems like a great fix to me! Best, Gabor On Mon, Mar 23, 2020 at 5:04 PM Tomas Kalibera wrote: > > To clarify, these issues are about deleting the contents of the home > directory, not the directory itself, which cannot be deleted by ordinary > users on today's systems. Unfortunately this has to be fixed in the code > that calls unlink(), such code must be aware of the expansions. The "R > CMD build" case as you write has been fixed, if anyone finds any other > instance of this problem in base R, please report, it will be fixed as > well. The new argument "expand" has been added to unlink() to make these > fixes easier. > > A variation on what you propose: tilde ("~") is now treated the same way > as "." and ".." have already been by unlink(), which means it will never > be considered for deletion (not even with expand=TRUE). There are still > a number of ways to delete the contents of one's home directory, > including tilde expansion with user name, with directory separators, > etc. This special treatment of "~" will prevent only one pattern of the > problem. One should always be careful when recursively/programmatically > deleting files. > > Also, the new behavior can cause trouble in some cases when a file or > directory named tilde exists, but hopefully not as bad as deleting the > contents of user home directory. In principle, such file can still be > deleted from R using a combination of tilde and wildcards with wildcard > expansion enabled. > > Best > Tomas > > On 2/26/20 11:47 PM, Gábor Csárdi wrote: > > !!! DON'T TRY THE CODE IN THIS EMAIL AT HOME !!! > > > > Well, unlink() does what it is supposed to do, so you could argue that > > there is nothing wrong with it. Also, nobody would call unlink() on > > "~", right? > > > > The situation is not so simple, however. E.g. if you happen to have a > > directory called "~", and you iterate over all files and directories > > to selectively remove some of them, then your code might end up > > calling unlink on the local "~" directory, and then your home is gone. > > > > But you would not create a directory named "~", that is just asking > > for trouble. Well, surely, _intentionally_ you would not do that. > > Unintentionally, you might. E.g. something like this is enough: > > > > # Create a subpath within a base directory > > badfun <- function(base = ".", path) { > >dir.create(file.path(base, path), recursive = TRUE, showWarnings = FALSE) > > } > > badfun(path = "~/foo") > > > > (If you did run this, be very careful how you remove the directory called > > "~"!) > > > > A real example is `R CMD build` which deletes the home directory of > > the current user if the root of the package contains a non-empty "~" > > directory. Luckily this is now fixed in R-devel, so R 4.0.0 will do > > better. (R 3.6.3 will not.) See > > https://github.com/wch/r-source/commit/1d4f7aa1dac427ea2213d1f7cd7b5c16e896af22 > > > > I have seen several bug reports about various packages (that call R > > CMD build) removing the home directory, so this indeed happens in > > practice to a number of people. The commit above will fix `R CMD > > build`, but it would be great to "fix" this in general. > > > > It seems pretty hard to prevent users from creating of a "~" > > directory. But preventing unlink() from deleting "~" does not actually > > seem too hard. If unlink() could just refuse removing "~" (when expand > > = TRUE), that would be great. It seems to me that the current behavior > > is very-very rarely intended, and its consequences are potentially > > disastrous. > > > > If unlink("~", recursive = TRUE) errors, you can still remove a local > > "~" file/dir with unlink("./~", ...). And you can still remove your > > home directory if you really want to do that, with > > unlink(path.expand("~"), ...). So no functionality is lost. > > > > Also, if anyone is aware of packages/functions that tend to create "~" > > directories or files, please let me know. > > > > I would be happy to submit a patch for the new unlink("~") behavior. > > > > Thanks, > > Gabor > > > > __ > > R-devel@r-project.org mailing list > > https://stat.ethz.ch/mailman/listinfo/r-devel > > __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
[Rd] help with rchk warnings on Rf_eval(Rf_lang2(...))
Dear r-devel folks, [if this is more appropriate for r-pkg-devel please let me know and I'll repost it over there ...] I'm writing to ask for help with some R/C++ integration idioms that are used in a package I'm maintaining, that are unfamilar to me, and that are now being flagged as problematic by Tomas Kalibera's 'rchk' machinery (https://github.com/kalibera/rchk); results are here https://raw.githubusercontent.com/kalibera/cran-checks/master/rchk/results/lme4.out The problem is with constructions like ::Rf_eval(::Rf_lang2(fun, arg), d_rho) I *think* this means "construct a two-element pairlist from fun and arg, then evaluate it within expression d_rho" This leads to warnings like "calling allocating function Rf_eval with argument allocated using Rf_lang2" Is this a false positive or ... ? Can anyone help interpret this? Not sure why this idiom was used in the first place: speed? (e.g., see https://stat.ethz.ch/pipermail/r-devel/2019-June/078020.html ) Should I be rewriting to avoid Rf_eval entirely in favor of using a Function? (i.e., as commented in https://stackoverflow.com/questions/37845012/rcpp-function-slower-than-rf-eval : "Also, calling Rf_eval() directly from a C++ context is dangerous as R errors (ie, C longjmps) will bypass the destructors of C++ objects and leak memory / cause undefined behavior in general. Rcpp::Function tries to make sure that doesn't happen.") Any tips, corrections, pointers to further documentation, etc. would be most welcome ... Web searching for this stuff hasn't gotten me very far, and it seems to be deeper than most of the introductory material I can find (including the Rcpp vignettes) ... cheers Ben Bolker __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] help with rchk warnings on Rf_eval(Rf_lang2(...))
On 3/23/20 8:39 PM, Ben Bolker wrote: Dear r-devel folks, [if this is more appropriate for r-pkg-devel please let me know and I'll repost it over there ...] I'm writing to ask for help with some R/C++ integration idioms that are used in a package I'm maintaining, that are unfamilar to me, and that are now being flagged as problematic by Tomas Kalibera's 'rchk' machinery (https://github.com/kalibera/rchk); results are here https://raw.githubusercontent.com/kalibera/cran-checks/master/rchk/results/lme4.out The problem is with constructions like ::Rf_eval(::Rf_lang2(fun, arg), d_rho) I *think* this means "construct a two-element pairlist from fun and arg, then evaluate it within expression d_rho" This leads to warnings like "calling allocating function Rf_eval with argument allocated using Rf_lang2" Is this a false positive or ... ? Can anyone help interpret this? This is a true error. You need to protect the argument of eval() before calling eval, otherwise eval() could destroy it before using it. This is a common rule: whenever passing an argument to a function, that argument must be protected (directly or indirectly). Rchk tries to be smart and doesn't report a warning when it can be sure that in that particular case, for that particular function, it is safe. This is easy to fix, just protect the result of lang2() before the call and unprotect (some time) after. Not sure why this idiom was used in the first place: speed? (e.g., see https://stat.ethz.ch/pipermail/r-devel/2019-June/078020.html ) Should I be rewriting to avoid Rf_eval entirely in favor of using a Function? (i.e., as commented in https://stackoverflow.com/questions/37845012/rcpp-function-slower-than-rf-eval : "Also, calling Rf_eval() directly from a C++ context is dangerous as R errors (ie, C longjmps) will bypass the destructors of C++ objects and leak memory / cause undefined behavior in general. Rcpp::Function tries to make sure that doesn't happen.") Yes, eval (as well as lang2) can throw an error, this error has to be caught via R API and handled (e.g. by throwing as exception or something else, indeed that exception then needs to be caught and possibly converted back when leaving again to C stack frames). An R/C API you can use here is R_UnwindProtect. This is of course a bit of a pain, and one does not have to worry when programming in plain C. I suppose Rcpp provides some wrapper around R_UnwindProtect, that would be a question for Rcpp experts/maintainers. Best Tomas Any tips, corrections, pointers to further documentation, etc. would be most welcome ... Web searching for this stuff hasn't gotten me very far, and it seems to be deeper than most of the introductory material I can find (including the Rcpp vignettes) ... cheers Ben Bolker __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] help with rchk warnings on Rf_eval(Rf_lang2(...))
Thanks, that's really useful. One more question for you, or someone else here: const ArrayXd glmLink::linkFun(const ArrayXd& mu) const { return as(::Rf_eval(::Rf_lang2(as(d_linkFun), as(Rcpp::NumericVector(mu.data(), mu.data() + mu.size())) ), d_rho); } I guess I need that to read PROTECT(::Rf_eval(PROTECT(::Rf_lang2(...),...) , but as written it doesn't seem I have anywhere to squeeze in an UNPROTECT(2). Do I need to define a temporary variable so I can UNPROTECT(2) before I return the value? Or is there a way I can use Shield() since this an Rcpp-based project anyway? Sorry for all the very basic questions, but I'm flying nearly blind here ... cheers Ben Bolker On 2020-03-23 4:01 p.m., Tomas Kalibera wrote: > On 3/23/20 8:39 PM, Ben Bolker wrote: >> Dear r-devel folks, >> >> [if this is more appropriate for r-pkg-devel please let me know and >> I'll repost it over there ...] >> >> I'm writing to ask for help with some R/C++ integration idioms that are >> used in a package I'm maintaining, that are unfamilar to me, and that >> are now being flagged as problematic by Tomas Kalibera's 'rchk' >> machinery (https://github.com/kalibera/rchk); results are here >> https://raw.githubusercontent.com/kalibera/cran-checks/master/rchk/results/lme4.out >> >> >> The problem is with constructions like >> >> ::Rf_eval(::Rf_lang2(fun, arg), d_rho) >> >> I *think* this means "construct a two-element pairlist from fun and arg, >> then evaluate it within expression d_rho" >> >> This leads to warnings like >> >> "calling allocating function Rf_eval with argument allocated using >> Rf_lang2" >> >> Is this a false positive or ... ? Can anyone help interpret this? > This is a true error. You need to protect the argument of eval() before > calling eval, otherwise eval() could destroy it before using it. This is > a common rule: whenever passing an argument to a function, that argument > must be protected (directly or indirectly). Rchk tries to be smart and > doesn't report a warning when it can be sure that in that particular > case, for that particular function, it is safe. This is easy to fix, > just protect the result of lang2() before the call and unprotect (some > time) after. >> Not sure why this idiom was used in the first place: speed? (e.g., see >> https://stat.ethz.ch/pipermail/r-devel/2019-June/078020.html ) Should I >> be rewriting to avoid Rf_eval entirely in favor of using a Function? >> (i.e., as commented in >> https://stackoverflow.com/questions/37845012/rcpp-function-slower-than-rf-eval >> >> : "Also, calling Rf_eval() directly from a C++ context is dangerous as R >> errors (ie, C longjmps) will bypass the destructors of C++ objects and >> leak memory / cause undefined behavior in general. Rcpp::Function tries >> to make sure that doesn't happen.") > > Yes, eval (as well as lang2) can throw an error, this error has to be > caught via R API and handled (e.g. by throwing as exception or something > else, indeed that exception then needs to be caught and possibly > converted back when leaving again to C stack frames). An R/C API you can > use here is R_UnwindProtect. This is of course a bit of a pain, and one > does not have to worry when programming in plain C. > > I suppose Rcpp provides some wrapper around R_UnwindProtect, that would > be a question for Rcpp experts/maintainers. > > Best > Tomas > >> >> Any tips, corrections, pointers to further documentation, etc. would be >> most welcome ... Web searching for this stuff hasn't gotten me very far, >> and it seems to be deeper than most of the introductory material I can >> find (including the Rcpp vignettes) ... >> >> cheers >> Ben Bolker >> >> __ >> R-devel@r-project.org mailing list >> https://stat.ethz.ch/mailman/listinfo/r-devel > > __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] help with rchk warnings on Rf_eval(Rf_lang2(...))
> Ben Bolker > on Mon, 23 Mar 2020 17:07:36 -0400 writes: > Thanks, that's really useful. One more question for you, or someone > else here: > const ArrayXd glmLink::linkFun(const ArrayXd& mu) const { > return as(::Rf_eval(::Rf_lang2(as(d_linkFun), > as(Rcpp::NumericVector(mu.data(), > mu.data() + mu.size())) > ), d_rho); > } > I guess I need that to read > PROTECT(::Rf_eval(PROTECT(::Rf_lang2(...),...) , but as written it > doesn't seem I have anywhere to squeeze in an UNPROTECT(2). Do I need > to define a temporary variable so I can UNPROTECT(2) before I return the > value? Ben, as co-author of the package, I could try .. I have lots of experience with (nice and clean) C API using PROTECT ... which I could try to apply here. I'm busy teaching tomorrow (with the extra time of setting up remote teaching ..) but could look into it later {and try using non-Rcpp C code}. > Or is there a way I can use Shield() since this an Rcpp-based project > anyway? > Sorry for all the very basic questions, but I'm flying nearly blind > here ... > cheers > Ben Bolker > On 2020-03-23 4:01 p.m., Tomas Kalibera wrote: >> On 3/23/20 8:39 PM, Ben Bolker wrote: >>> Dear r-devel folks, >>> >>> [if this is more appropriate for r-pkg-devel please let me know and >>> I'll repost it over there ...] >>> >>> I'm writing to ask for help with some R/C++ integration idioms that are >>> used in a package I'm maintaining, that are unfamilar to me, and that >>> are now being flagged as problematic by Tomas Kalibera's 'rchk' >>> machinery (https://github.com/kalibera/rchk); results are here >>> https://raw.githubusercontent.com/kalibera/cran-checks/master/rchk/results/lme4.out >>> >>> >>> The problem is with constructions like >>> >>> ::Rf_eval(::Rf_lang2(fun, arg), d_rho) >>> >>> I *think* this means "construct a two-element pairlist from fun and arg, >>> then evaluate it within expression d_rho" >>> >>> This leads to warnings like >>> >>> "calling allocating function Rf_eval with argument allocated using >>> Rf_lang2" >>> >>> Is this a false positive or ... ? Can anyone help interpret this? >> This is a true error. You need to protect the argument of eval() before >> calling eval, otherwise eval() could destroy it before using it. This is >> a common rule: whenever passing an argument to a function, that argument >> must be protected (directly or indirectly). Rchk tries to be smart and >> doesn't report a warning when it can be sure that in that particular >> case, for that particular function, it is safe. This is easy to fix, >> just protect the result of lang2() before the call and unprotect (some >> time) after. >>> Not sure why this idiom was used in the first place: speed? (e.g., see >>> https://stat.ethz.ch/pipermail/r-devel/2019-June/078020.html ) Should I >>> be rewriting to avoid Rf_eval entirely in favor of using a Function? >>> (i.e., as commented in >>> https://stackoverflow.com/questions/37845012/rcpp-function-slower-than-rf-eval >>> >>> : "Also, calling Rf_eval() directly from a C++ context is dangerous as R >>> errors (ie, C longjmps) will bypass the destructors of C++ objects and >>> leak memory / cause undefined behavior in general. Rcpp::Function tries >>> to make sure that doesn't happen.") >> >> Yes, eval (as well as lang2) can throw an error, this error has to be >> caught via R API and handled (e.g. by throwing as exception or something >> else, indeed that exception then needs to be caught and possibly >> converted back when leaving again to C stack frames). An R/C API you can >> use here is R_UnwindProtect. This is of course a bit of a pain, and one >> does not have to worry when programming in plain C. >> >> I suppose Rcpp provides some wrapper around R_UnwindProtect, that would >> be a question for Rcpp experts/maintainers. >> >> Best >> Tomas >> >>> >>> Any tips, corrections, pointers to further documentation, etc. would be >>> most welcome ... Web searching for this stuff hasn't gotten me very far, >>> and it seems to be deeper than most of the introductory material I can >>> find (including the Rcpp vignettes) ... >>> >>> cheers >>> Ben Bolker >>> >>> __ >>> R-devel@r-project.org mailing list >>> https://stat.ethz.ch/mailman/listinfo/r-devel >> >> > __ > R-devel@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] help with rchk warnings on Rf_eval(Rf_lang2(...))
Ben, yes, you have to store the result into a variable, then unprotect, then return. Cheers, S > On 24/03/2020, at 10:07 AM, Ben Bolker wrote: > > > Thanks, that's really useful. One more question for you, or someone > else here: > > const ArrayXd glmLink::linkFun(const ArrayXd& mu) const { >return as(::Rf_eval(::Rf_lang2(as(d_linkFun), > > as(Rcpp::NumericVector(mu.data(), > > mu.data() + mu.size())) > ), d_rho); >} > > > I guess I need that to read > PROTECT(::Rf_eval(PROTECT(::Rf_lang2(...),...) , but as written it > doesn't seem I have anywhere to squeeze in an UNPROTECT(2). Do I need > to define a temporary variable so I can UNPROTECT(2) before I return the > value? > > Or is there a way I can use Shield() since this an Rcpp-based project > anyway? > > Sorry for all the very basic questions, but I'm flying nearly blind > here ... > > cheers > Ben Bolker > > > > On 2020-03-23 4:01 p.m., Tomas Kalibera wrote: >> On 3/23/20 8:39 PM, Ben Bolker wrote: >>> Dear r-devel folks, >>> >>>[if this is more appropriate for r-pkg-devel please let me know and >>> I'll repost it over there ...] >>> >>> I'm writing to ask for help with some R/C++ integration idioms that are >>> used in a package I'm maintaining, that are unfamilar to me, and that >>> are now being flagged as problematic by Tomas Kalibera's 'rchk' >>> machinery (https://github.com/kalibera/rchk); results are here >>> https://raw.githubusercontent.com/kalibera/cran-checks/master/rchk/results/lme4.out >>> >>> >>> The problem is with constructions like >>> >>> ::Rf_eval(::Rf_lang2(fun, arg), d_rho) >>> >>> I *think* this means "construct a two-element pairlist from fun and arg, >>> then evaluate it within expression d_rho" >>> >>> This leads to warnings like >>> >>> "calling allocating function Rf_eval with argument allocated using >>> Rf_lang2" >>> >>> Is this a false positive or ... ? Can anyone help interpret this? >> This is a true error. You need to protect the argument of eval() before >> calling eval, otherwise eval() could destroy it before using it. This is >> a common rule: whenever passing an argument to a function, that argument >> must be protected (directly or indirectly). Rchk tries to be smart and >> doesn't report a warning when it can be sure that in that particular >> case, for that particular function, it is safe. This is easy to fix, >> just protect the result of lang2() before the call and unprotect (some >> time) after. >>> Not sure why this idiom was used in the first place: speed? (e.g., see >>> https://stat.ethz.ch/pipermail/r-devel/2019-June/078020.html ) Should I >>> be rewriting to avoid Rf_eval entirely in favor of using a Function? >>> (i.e., as commented in >>> https://stackoverflow.com/questions/37845012/rcpp-function-slower-than-rf-eval >>> >>> : "Also, calling Rf_eval() directly from a C++ context is dangerous as R >>> errors (ie, C longjmps) will bypass the destructors of C++ objects and >>> leak memory / cause undefined behavior in general. Rcpp::Function tries >>> to make sure that doesn't happen.") >> >> Yes, eval (as well as lang2) can throw an error, this error has to be >> caught via R API and handled (e.g. by throwing as exception or something >> else, indeed that exception then needs to be caught and possibly >> converted back when leaving again to C stack frames). An R/C API you can >> use here is R_UnwindProtect. This is of course a bit of a pain, and one >> does not have to worry when programming in plain C. >> >> I suppose Rcpp provides some wrapper around R_UnwindProtect, that would >> be a question for Rcpp experts/maintainers. >> >> Best >> Tomas >> >>> >>> Any tips, corrections, pointers to further documentation, etc. would be >>> most welcome ... Web searching for this stuff hasn't gotten me very far, >>> and it seems to be deeper than most of the introductory material I can >>> find (including the Rcpp vignettes) ... >>> >>>cheers >>> Ben Bolker >>> >>> __ >>> R-devel@r-project.org mailing list >>> https://stat.ethz.ch/mailman/listinfo/r-devel >> >> > > __ > R-devel@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel > __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel