Search code examples
c++crrcpprestrict-qualifier

Building an R package with Rcpp which contains C source and header with restrict qualifier?


I have an third party source file and corresponding header (containing the declarations and include directives for GSL etc) which are written in C. I am trying to build an R package around these source files, basically making a wrappers for the functions using Rcpp. Problem is that these files contain restrict qualifier which is not part of the C++ standard, so R CMD INSTALL cannot compile the package. It does use C compiler for .c file, but want's to compile .h file with C++ compiler and it fails. it fails when it finds restrict in header file (which is included in .cpp file).

I am not that familiar with C and compiler things and Rcpp etc, so I am not sure what would be a best approach here?

Easiest thing would probably be to remove the restrict keyword. This is what I have currently done (I am suprised that R CMD INSTALL works when I remove restrict from header file but leave them to .c file). But I rather not alter the .c and .h files as they are also used in non-R environment by others (executable and in Python) and it would be nice to have identical files for all projects.

I also tried to define empty keyword restrict so that it would just "remove" restrict from function definitions if the compilation was done in C++ compiler, but I couldn't get that work. I read about similar approach somewhere but apparently it doesn't work that way.

Would it work if I could somehow tell the compiler (via Makevars or something?) that the particular .h file should be compiled with C compiler? Or is there going to be problems with C++ function calling those functions?

Or will the whole keyword even matter in terms of performance if those functions are called from R via C++ wrapper?

One thing would be to just ditch the Rcpp and use .C instead of .Call from R, but as the performance is a key here, that doesn't feel a good option, as I understand that .Call is faster (and more reliable).

Note that eventually this package could find it's way to CRAN, so the solution should be fairly portable. There seems to be some C++ compiler specific keywords for restrict but I guess those are not an option due to the portability.


Solution

  • It sounds like you are making a .cpp file which does #include <x.h> where x.h is a C header which uses restrict. If that's true, I think you can modify your .cpp file to do this:

    #define restrict // nothing
    extern "C"
    {
    #include <x.h>
    }
    

    Then compilation of your C++ code will not see the restrict keyword, and also I have wrapped the header in extern "C" because if the header itself doesn't do that internally, you need to, in order that your C++ compiler will not apply C++ "name mangling" to the functions declared inside.