[Rcpp-devel] [Summary] (Was: question re: LdFlags, RcppLdFlags

Romain Francois romain at r-enthusiasts.com
Thu Oct 10 17:15:35 CEST 2013

Le 10/10/13 16:51, Dirk Eddelbuettel a écrit :
> To bring a bit of closure to this endless thread: It appear from his commit
> logs that Romain made the change in his dplyRcpp project we are now supposed
> to make per R Core: Demote packages from Depends: to Imports:, and import
> what is needed.
> That, as best as I can tell, seems to be the way to avoid the clashes seen in
> Romain's first email in this thread.
> Some more questions re some possible future use below
> On 10 October 2013 at 05:15, Romain Francois wrote:
> | I don't particularly love macros. I much prefer templates. For example
> | in Rcpp11, I replaced thousands lines worth of macros code bloat with a
> | few dozens of lines of templates.
> Good to see Romain-the-template-whiz clean up after Romain-the-macro-user. :)
> And obviously I don't mind all the macros as your use of these macros gives
> us all thse awesome features in Rcpp. But macros are a last resort...

Sure. I'm counting 515 macros in Rcpp:

% grep "#define" **/* * 2> /dev/null | grep -v "_h" | grep -v "_H" | wc -l

And only 137 in Rcpp11

% grep "#define" **/* 2> /dev/null | grep -v "_h" | grep -v "_H" | wc -l

Macros are evil for things like this:

#define CONSTANT 42
#define max(x,y) (x>y):x?y ;

which can be replaced by const int and inline function. This is 
Effective C++ item #2.

They however can have a role to play in code generation. Here is one 
from Rcpp11:

#define DOT_CALL(name) DotCall(#name, &name)

So that one can write:


instead of DotCall("foo", foo)

They are quite useful for debugging too:

#define RCPP_DEBUG( fmt, ... ) Rprintf( "%20s:%4d             " fmt "\n" 
, short_file_name(__FILE__), __LINE__, ##__VA_ARGS__ ) ;
#define RCPP_DEBUG( MSG, ... )

So that we can write:

RCPP_DEBUG( "bla bla %d", 42 )

and leave it there when the code is not debugged.

> | Would be easy enough to come up with a way to automatically generate
> | things automatically.
> |
> | A package author could leverage tools:::read_symbols_from_object_file,
> | i.e. here are all the symbols in Rcpp.so:
> |
> | symbols <- tools:::read_symbols_from_object_file( system.file( "libs",
> | "Rcpp.so", package = "Rcpp" ) )[,1]
> |
> | Would be easy to then come up with a naming convention, and generate the
> | registration.
> |
> | read_symbols_from_object_file is why we have been all of a sudden
> | forbidden to use functions that R exposes but "not part of the api".
> Can you (portably, with all (major) compilers and OS choices) pick out
> symbols even when they have attribute_hidden set as R does all over its
> sources?


But since that sort of thing are typically the task of the package 
maintainer: I don't care.

read_symbols_from_object_file is just a convoluted way to call nm.

function (f)
     if (!nzchar(nm <- Sys.which("nm")))
     f <- file_path_as_absolute(f)
     if (!(file.info(f)$size))
     s <- strsplit(system(sprintf("%s -Pg %s", shQuote(nm), shQuote(f)),
         intern = TRUE), " +")
     n <- length(s)
     tab <- matrix("", nrow = n, ncol = 4L)
     colnames(tab) <- c("name", "type", "value", "size")
     i <- rep.int(seq_len(n), sapply(s, length))
     j <- unlist(lapply(s, seq_along))
     tab[n * (j - 1L) + i] <- unlist(s)

on windows, there is an equivalent function that does the windows thing.

But again, I don't care. Generating code is the task of the package 
maintainer, so if I want to use something like that, it just has to work 
on whatever I use.

That's similar to calling compileAttributes, or generating the code 
bloat we've put in Rcpp with the generator scripts.

Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30

More information about the Rcpp-devel mailing list