From bhh at xs4all.nl  Tue Mar  6 15:46:29 2012
From: bhh at xs4all.nl (Berend Hasselman)
Date: Tue, 6 Mar 2012 15:46:29 +0100
Subject: [Rd] Calling FORTRAN function from R issue?
In-Reply-To: <4F561C79.2090002@stats.ox.ac.uk>
References: <CADUbQ5ghmCd-3K4hx=FrzhA8YwfohhUp0-g6rJHHU0s-uEfN+A@mail.gmail.com>
	<B1B70BE3-2D8A-495B-8893-CC67026E1E9F@xs4all.nl>
	<20120306195608.7ec858c0@bossiaea>
	<879BAEC9-1963-4574-B962-CA8CC9D4F13B@xs4all.nl>
	<20120306213703.6a5a091f@absentia>
	<4F561C79.2090002@stats.ox.ac.uk>
Message-ID: <D0D80B8E-E5A8-457E-9399-09EFA3570E79@xs4all.nl>


On 06-03-2012, at 15:17, Prof Brian Ripley wrote:

>> [..]
>> used to indicate that the function/variable/symbol is defined in
>> another compilation unit.  In FORTRAN77, "external" is used to tell the
>> compiler that you are passing a function to another
>> function/subroutine.  At least that is my understanding from what I
>> re-read in my FORTRAN documentation.
> 
> Not quite.  It also means that you really want to externally link and not allow the compiler to find any routine of that name it knows about (e.g. an intrinsic).  See para 8.7 of http://www.fortran.com/F77_std/rjcnf-8.html (although I got this from my Fortran reference on my bookshelf).
> 
>> Thus, perhaps strangely, if there is only a
>> 	external double complex zdotc
>> declaration in your subroutine, the compiler doesn't know that a call
> 
> The only 'strangely' thing is that is accepted: AFAICS is it not valid according to the link above.
> 

Agree. The fortran 77 standard doesn't allow that syntax and I'm really surprised that no error is flagged.

>> to zdotc will return a double complex but will assume that the result
>> has the implicitly defined type, a real*8 IIRC.
> 
> The Fortran default type for z* is real.
> 
> > So zdotc is called, and
>> puts a double complex as result on the stack (heap?), but within
>> callzdotc a real as return is expected and that is taken from the
>> stack (heap?), that real is than coerced to a double complex when
>> assigned to retval.  Note that while I am pretty sure about the above,
>> this last paragraph is more speculative. :)  But it would explain why
>> the erroneous code returns 0 on little-endian machines.
> 
> We haven't been told which machines, and this actually matters down to the level of optimization used by the compilers.  But these days typically double complex gets passed in sse registers, and double is passed in fpu registers.
> 

Mac OS X 10.6.8, Mini Core 2 Duo
Apple gcc (i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5664))
and gfortran (GNU Fortran (GCC) 4.2.1 (Apple Inc. build 5664)) from r.research.att.com.

Output from  R CMD SHLIB --output=dozdot.so callzdotc.f czdot.c 

gfortran -arch x86_64   -fPIC  -g -O2 -c callzdotc.f -o callzdotc.o
gcc -arch x86_64 -std=gnu99 -I/Library/Frameworks/R.framework/Resources/include -I/Library/Frameworks/R.framework/Resources/include/x86_64  -I/usr/local/include    -fPIC  -g -O2 -c czdot.c -o czdot.o
gcc -arch x86_64 -std=gnu99 -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module -multiply_defined suppress -L/usr/local/lib -o dozdot.so callzdotc.o czdot.o -lgfortran -F/Library/Frameworks/R.framework/.. -framework R -Wl,-framework -Wl,CoreFoundation

Same thing happens with gcc (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1 and gfortran on Xubuntu 11.10 64-bit.

Berend



[Rd] Calling FORTRAN function from R issue?
Berend Hasselman