[R] Passing single precision arrays to legacy code

Allen McIntosh mcintosh at research.telcordia.com
Thu May 17 17:46:39 CEST 2007

System: Fedora Core 5
R: 2.2.1 and 2.4.1, complied from source
gcc: 4.1.1

I'm trying to pass a single precision array to some legacy code.  I 
ultimately got the code working by ignoring part of the help 
documentation.  The code is actually in Fortran, but the following C 
program illustrates the problem:

$  cat foo.c
#include <stdio.h>
foo(float *t) {
         int *bar;
         float f;
         double d;
         bar = (int *) t;
         printf("hello world\n");
         printf("%f %f\n", t[0], t[1]);
         printf("%08x %08x %08x\n", bar[0], bar[1], bar[2]);
         f = 1.0;
         bar = (int *)&f;
         printf("(float) 1.0 in hex: %08x\n", bar[0]);
         d = 1.0;
         bar = (int *)&d;
         printf("(double) 1.0 in hex: %08x %08x\n", bar[0], bar[1]);

$ gcc -O0 -c foo.c
$ gcc -shared -o foo.so foo.o
$ R

R version 2.4.1 (2006-12-18)
Copyright (C) 2006 The R Foundation for Statistical Computing
ISBN 3-900051-07-0

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

 > dyn.load("foo.so")
 > .C("foo", as.single(1:3), DUP=F, PACKAGE="foo")
hello world
0.000000 1.875000
00000000 3ff00000 00000000
(float) 1.0 in hex: 3f800000
(double) 1.0 in hex: 00000000 3ff00000
[1] 1 2 3
[1] TRUE

It's pretty clear from this that the array is getting passed as double, 
despite the documentation:

 > help(.C)
... stuff omitted...
      Numeric vectors in R will be passed as type 'double *' to C (and
      as 'double precision' to Fortran) unless (i) '.C' or '.Fortran' is
      used, (ii) 'DUP' is false and (iii) the argument has attribute
      'Csingle' set to 'TRUE' (use 'as.single' or 'single').  This
      mechanism is only intended to be used to facilitate the
      interfacing of existing C and Fortran code.

The online "Writing R Extensions" document doesn't mention DUP, and 
indeed the following works:

 > .C("foo", as.single(1:3), DUP=T, PACKAGE="foo")
hello world
1.000000 2.000000
3f800000 40000000 40400000
(float) 1.0 in hex: 3f800000
(double) 1.0 in hex: 00000000 3ff00000
[1] 1 2 3
[1] TRUE

So is the help document incorrect?

More information about the R-help mailing list