Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

module

87 views
Skip to first unread message

rudra

unread,
Jul 28, 2009, 3:08:44 AM7/28/09
to
Is there any way to check if a module that contains a subroutine is
compiled and included correctly in the executable before running the
job?

Bil Kleb

unread,
Jul 28, 2009, 4:33:09 AM7/28/09
to

On *nix systems, I might use strings to find a known character string
in the executable, e.g.,

% strings executable | grep 'character string'

Regards,
--
Bil Kleb
http://fun3d.larc.nasa.gov

Louis Krupp

unread,
Jul 28, 2009, 6:46:00 AM7/28/09
to
Bil Kleb wrote:
> rudra wrote:
>> Is there any way to check if a module that contains a subroutine is
>> compiled and included correctly in the executable before running the
>> job?
>
> On *nix systems, I might use strings to find a known character string
> in the executable, e.g.,
>
> % strings executable | grep 'character string'

The names of the module and/or subroutine might not be in the executable
if it was compiled without the debug flag. On the other hand, if other
code includes a string with the name you're looking for, the strings
command might give you a misleading result.

If the code structure makes sense and the Makefile works properly, there
shouldn't be an executable unless everything was compiled and linked
correctly.

Louis

AnotherSquid

unread,
Jul 28, 2009, 9:31:55 AM7/28/09
to
On Jul 28, 4:46 am, Louis Krupp <lkrupp_nos...@indra.com.invalid>
wrote:

> The names of the module and/or subroutine might not be in the executable
> if it was compiled without the debug flag.

Actually they are always in there. You just need to wrench them out
with the nm command. E.g., my program contains a subroutine named
MMATMUL.

% nm a.out | grep -i mmatmul
0804a240 T mmatmul_
080a8a80 r mmatmul_$BLK$format_pack.0.2
0804a24c T mmatmul_.
%

The capital-t in the output means that there is something in a.out
called mmatmul. If the capital-t is a capital-u then the name is
referenced somewhere in there, but not defined ("U" means undefined).

Andy

James Van Buskirk

unread,
Jul 28, 2009, 1:34:30 PM7/28/09
to
"rudra" <bnrj....@gmail.com> wrote in message
news:de982d43-d819-4dc6...@l5g2000pra.googlegroups.com...

> Is there any way to check if a module that contains a subroutine is
> compiled and included correctly in the executable before running the
> job?

Yeah, I have noticed that this is a problem with a version of gfortran
that I have been using:

C:\gfortran\clf\makedll>gfortran -v
Built by Equation Solution <http://www.Equation.com>.
Using built-in specs.
Target: x86_64-pc-mingw32
Configured with:
../gcc-4.5-20090514-mingw/configure --host=x86_64-pc-mingw32 --
build=x86_64-unknown-linux-gnu --target=x86_64-pc-mingw32 --prefix=/home/gfortra
n/gcc-home/binary/mingw32/native/x86_64/gcc/4.5-20090514 --with-gmp=/home/gfortr
an/gcc-home/binary/mingw32/native/x86_64/gmp --with-mpfr=/home/gfortran/gcc-home
/binary/mingw32/native/x86_64/mpfr --with-sysroot=/home/gfortran/gcc-home/binary
/mingw32/cross/x86_64/gcc/4.5-20090514 --with-gcc --with-gnu-ld --with-gnu-as
--
disable-shared --disable-nls --disable-tls --enable-libgomp --enable-languages=c
,fortran,c++ --enable-threads=win32 --disable-win32-registry
Thread model: win32
gcc version 4.5.0 20090514 (experimental) (GCC)

If something is not found at link time, no error is printed, you only find
out when you try to run the executable and it's not there.

I point out that in general a procedure need not be compiled when the
program is compiled or even run to work:

C:\gfortran\clf\makedll>type makedll.f90
program makedll
use ISO_C_BINDING
implicit none
interface
function LoadLibrary(lpFileName) bind(C,name='LoadLibraryA')
use ISO_C_BINDING
implicit none
integer(C_INTPTR_T) LoadLibrary
character(kind=C_CHAR) lpFileName(*)
end function LoadLibrary
function GetLastError() bind(C,name='GetLastError')
use ISO_C_BINDING
implicit none
integer(C_LONG) GetLastError
end function GetLastError
function GetProcAddress(hModule, lpProcName)
bind(C,name='GetProcAddress')

use ISO_C_BINDING
implicit none
type(C_FUNPTR) GetProcAddress
integer(C_INTPTR_T), value :: hModule
character(kind=C_CHAR) lpProcName(*)
end function GetProcAddress
function simpson(f,a,b,n)
use ISO_C_BINDING
implicit none
real(C_double) simpson
interface
function f(x) bind(C)
use ISO_C_BINDING
implicit none
real(C_DOUBLE) f, x
end function f
end interface
real(C_DOUBLE) a, b
integer(C_INT) n
end function simpson
end interface
abstract interface
function dllfun(x)
use ISO_C_BINDING
implicit none
real(C_DOUBLE) dllfun, x
end function dllfun
end interface
integer(C_INTPTR_T) hmodule
integer(C_LONG) error
type(C_FUNPTR) FunAddress
procedure(dllfun), pointer :: fptr
real(C_DOUBLE) a, b
integer(C_INT) n
integer status

call system('del fun.*')
open(10,file='fun.f90',status='new')
write(10,'(a)') 'function fun(x) bind(C,name="fun")'
write(10,'(a)') ' use ISO_C_BINDING'
write(10,'(a)') ' implicit none'
write(10,'(a)') ' real(C_DOUBLE) fun, x'
write(10,'(a)') ''
write(10,'(a)') ' fun = x**2+3*x+2'
write(10,'(a)') 'end function fun'
close(10)
call system('gfortran fun.f90 -shared -ofun.dll', status)
write(*,'(a,i0)') 'status = ', status
if(status /= 0) stop
hmodule = LoadLibrary('fun.dll'//achar(0))
error = GetLastError()
write(*,'(a,z16.16)') 'hmodule = ', hmodule
if(hModule == 0) write(*,*) error
FunAddress = GetProcAddress(hmodule, 'fun'//achar(0))
error = GetLastError()
write(*,'(a,z16.16)') 'FunAddress = ',transfer(FunAddress,1_C_INTPTR_T)
if(.NOT.C_ASSOCIATED(FunAddress)) write(*,*) error
call C_F_PROCPOINTER(FunAddress, fptr)
a = 2
b = 3
n = 100
write(*,*) (b**3-a**3)/3+3*(b**2-a**2)/2+2*(b-a), simpson(fptr,a,b,n)
end program makedll

function simpson(f,a,b,n)
use ISO_C_BINDING
implicit none
real(C_double) simpson
interface
function f(x) bind(C)
use ISO_C_BINDING
implicit none
real(C_DOUBLE) f, x
end function f
end interface
real(C_DOUBLE) a, b
integer(C_INT) n
real(C_DOUBLE) h
integer(C_INT) i

h = (b-a)/n
simpson = f(a)
do i = 1, n-1
simpson = simpson+(3-(-1)**i)*f(a+i*h)
end do
simpson = simpson+f(b)
simpson = simpson*h/3
end function simpson

C:\gfortran\clf\makedll>del *.dll

C:\gfortran\clf\makedll>gfortran makedll.f90 -omakedll

C:\gfortran\clf\makedll>makedll
status = 0
hmodule = 000000006D5C0000
FunAddress = 000000006D5C1420
15.833333333333332 15.833333333333342

Dynamic linking means that you can have your Fortran program write
the procedure it's going to link to, then direct its compilation
and link to the *.dll file and use the compiled function, all at
run time.

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


Bil Kleb

unread,
Jul 28, 2009, 2:05:27 PM7/28/09
to
Louis Krupp wrote:
> [...] On the other hand, if other
> code includes a string with the name you're looking for, the strings
> command might give you a misleading result.

That's what I meant by "known string" (but failed to communicate),
In other words, you'd need to set something like,

character(30), parameter :: &
unique_for_external_check='zz44_present_and_accounted_for'

in the subroutine that you're trying to find.

Or just use nm to find the module/subroutine names directly
as other posters have suggested.

Louis Krupp

unread,
Jul 28, 2009, 3:02:08 PM7/28/09
to

You're right; I don't know what I was thinking when I said it would
depend on the presence of debug info.

If you don't take the extra step of including a marker string, then it's
up to nm. And if the executable is stripped (something which is of
course not usually done except for final production code), even nm won't
find anything.

I still believe that reasonable code structure and Makefile are the best
way to make sure the right stuff gets into the executable.

Louis

Dick Hendrickson

unread,
Jul 28, 2009, 4:31:07 PM7/28/09
to
The other problem with trying to force in a unique string is that
the compiler might not include the constant unless it's
actually used in the computation somewhere. And even then, it
might create it on the fly (usually if it's a smallish integer)
rather than allocate storage. What happens is likely to depend
on the optimization level.

Dick Hendrickson

James Van Buskirk

unread,
Jul 28, 2009, 7:56:05 PM7/28/09
to
"James Van Buskirk" <not_...@comcast.net> wrote in message
news:h4ncr8$rli$1...@news.eternal-september.org...

> Yeah, I have noticed that this is a problem with a version of gfortran
> that I have been using:

OK, I finally broke down and installed 32-bit gfortran on this
machine (my 32-bit machine has died) and I've got some problems:

C:\gfortran32\clf\makedll>gfortran -v
Using built-in specs.
Target: i586-pc-mingw32
Configured with:
../gcc-trunk/configure --prefix=/mingw --enable-languages=c,for
tran --with-gmp=/home/FX/gfortran/dependencies --disable-werror --enable-threads
--disable-nls --build=i586-pc-mingw32 --enable-libgomp --disable-shared --disab
le-win32-registry --with-dwarf2 --disable-sjlj-exceptions
Thread model: win32
gcc version 4.5.0 20090421 (experimental) [trunk revision 146519] (GCC)

C:\gfortran32\clf\makedll>type makedll.f90

C:\gfortran32\clf\makedll>gfortran
makedll.f90 -mrtd -enable-stdcall-fixup -omak
edll
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccwMTlPE.o:makedll.f90:(.text+0x537):
undefin
ed reference to `_LoadLibraryA'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccwMTlPE.o:makedll.f90:(.text+0x545):
undefin
ed reference to `_GetLastError'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccwMTlPE.o:makedll.f90:(.text+0x688):
undefin
ed reference to `_GetLastError'
collect2: ld returned 1 exit status

So this version still has the problem that name mangling doesn't seem
to be working. Also I tried the !gcc$ ATTRIBUTES stuff:

C:\gfortran32\clf\makedll>type makedll1.f90


program makedll
use ISO_C_BINDING
implicit none
interface
function LoadLibrary(lpFileName) bind(C,name='LoadLibraryA')

!gcc$ ATTRIBUTES STDCALL :: LoadLibrary


use ISO_C_BINDING
implicit none
integer(C_INTPTR_T) LoadLibrary
character(kind=C_CHAR) lpFileName(*)
end function LoadLibrary
function GetLastError() bind(C,name='GetLastError')

!gcc$ ATTRIBUTES STDCALL :: GetLastError


use ISO_C_BINDING
implicit none
integer(C_LONG) GetLastError
end function GetLastError
function GetProcAddress(hModule, lpProcName)
bind(C,name='GetProcAddress')

!gcc$ ATTRIBUTES STDCALL :: GetProcAddress

C:\gfortran32\clf\makedll>gfortran makedll1.f90 -omakedll1
Warning: resolving _GetProcAddress by linking to _GetProcAddress@8
Use --enable-stdcall-fixup to disable these warnings
Use --disable-stdcall-fixup to disable these fixups
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\cc8h6pfp.o:makedll1.f90:(.text+0x4dd):
undefi
ned reference to `_LoadLibraryA'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\cc8h6pfp.o:makedll1.f90:(.text+0x4e8):
undefi
ned reference to `_GetLastError'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\cc8h6pfp.o:makedll1.f90:(.text+0x613):
undefi
ned reference to `_GetLastError'
collect2: ld returned 1 exit status

Am I just doing everything wrong, or is this stuff not working
in gfortran?

steve

unread,
Jul 28, 2009, 9:08:24 PM7/28/09
to
On Jul 28, 4:56 pm, "James Van Buskirk" <not_va...@comcast.net> wrote:
> "James Van Buskirk" <not_va...@comcast.net> wrote in messagenews:h4ncr8$rli$1...@news.eternal-september.org...

>
> > Yeah, I have noticed that this is a problem with a version of gfortran
> > that I have been using:
>
> OK, I finally broke down and installed 32-bit gfortran on this
> machine (my 32-bit machine has died) and I've got some problems:
>
> C:\gfortran32\clf\makedll>gfortran -v
> Using built-in specs.
> Target: i586-pc-mingw32
> Configured with:
> ../gcc-trunk/configure --prefix=/mingw --enable-languages=c,for
> tran --with-gmp=/home/FX/gfortran/dependencies --disable-werror --enable-threads
>  --disable-nls --build=i586-pc-mingw32 --enable-libgomp --disable-shared --disab
> le-win32-registry --with-dwarf2 --disable-sjlj-exceptions
> Thread model: win32
> gcc version 4.5.0 20090421 (experimental) [trunk revision 146519] (GCC)

(snip)

> So this version still has the problem that name mangling doesn't seem
> to be working.  Also I tried the !gcc$ ATTRIBUTES stuff:

(snip)

> Am I just doing everything wrong, or is this stuff not working
> in gfortran?

The version of gfortran that you have is too old. The !GCC$
attribute feature was committed on 28 Jun 09.

The unfortunate reality is that none of the gfortran developers
are MingW/cygwin users, so the creation of binary snapshots is
often neglected (too much to do, too little time). If anyone
who uses one of these platforms wants to contribute to gfortran,
drop an email to fortran @ gcc dot gnu dot org. I suspect you
have more than one offer to help setup a build environment.

--
steve

James Van Buskirk

unread,
Jul 28, 2009, 9:13:37 PM7/28/09
to
"James Van Buskirk" <not_...@comcast.net> wrote in message
news:h4o36m$ht9$1...@news.eternal-september.org...

> Am I just doing everything wrong, or is this stuff not working
> in gfortran?

OK, the version of gfortran I got from the gfortran web page was
ancient history and wasn't at all recognizing the !gcc$ stuff.
I got the http://www.equation.com version:

C:\gcc-equation32\clf\makedll>gfortran -v


Built by Equation Solution <http://www.Equation.com>.
Using built-in specs.

Target: i386-pc-mingw32
Configured with:
../gcc-4.5-20090723-mingw/configure --host=i386-pc-mingw32 --bu
ild=x86_64-unknown-linux-gnu --target=i386-pc-mingw32 --prefix=/home/gfortran/gc
c-home/binary/mingw32/native/x86_32/gcc/4.5-20090723 --with-gcc --with-gnu-ld
--
with-gnu-as --disable-shared --disable-nls --disable-tls --with-gmp=/home/gfortr
an/gcc-home/binary/mingw32/native/x86_32/gmp --with-mpfr=/home/gfortran/gcc-home
/binary/mingw32/native/x86_32/mpfr --enable-languages=c,fortran,c++ --with-sysro
ot=/home/gfortran/gcc-home/binary/mingw32/cross/x86_32/gcc/4.5-20090723 --enable
-libgomp --enable-threads=win32 --disable-win32-registry
Thread model: win32
gcc version 4.5.0 20090723 (experimental) (GCC)

C:\gcc-equation32\clf\makedll>type makedll1.f90


program makedll
use ISO_C_BINDING
implicit none
interface
function LoadLibrary(lpFileName) bind(C,name='LoadLibraryA')

use ISO_C_BINDING
implicit none
!gcc$ ATTRIBUTES STDCALL :: LoadLibrary


integer(C_INTPTR_T) LoadLibrary
character(kind=C_CHAR) lpFileName(*)
end function LoadLibrary
function GetLastError() bind(C,name='GetLastError')
use ISO_C_BINDING
implicit none

!gcc$ ATTRIBUTES STDCALL :: GetLastError


integer(C_LONG) GetLastError
end function GetLastError
function GetProcAddress(hModule, lpProcName)
bind(C,name='GetProcAddress')

use ISO_C_BINDING
implicit none
!gcc$ ATTRIBUTES STDCALL :: GetProcAddress

C:\gcc-equation32\clf\makedll>gfortran makedll1.f90 -omakedll1
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccWdpOGC.o:makedll1.f90:(.text+0x4bc):
undefi
ned reference to `LoadLibraryA@8'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccWdpOGC.o:makedll1.f90:(.text+0x5d8):
undefi
ned reference to `GetProcAddress@12'


collect2: ld returned 1 exit status

Now the problem seems to be that gfortran is asking for 8 bytes rather
than 4 for LoadLibrary and 12 bytes rather than 8 for GetProcAddress.
Is this a problem with trying to account for a hidden LEN argument or
pointer size? Anyhow it's a bug in gfortran. The style with -mrtd
isn't working at all in this version, BTW.

steve

unread,
Jul 28, 2009, 9:59:53 PM7/28/09
to
On Jul 28, 6:13 pm, "James Van Buskirk" <not_va...@comcast.net> wrote:
> "James Van Buskirk" <not_va...@comcast.net> wrote in messagenews:h4o36m$ht9$1...@news.eternal-september.org...

>
> > Am I just doing everything wrong, or is this stuff not working
> > in gfortran?
>
> OK, the version of gfortran I got from the gfortran web page was
> ancient history and wasn't at all recognizing the !gcc$ stuff.
> I got thehttp://www.equation.comversion:

(snip)

> C:\gcc-equation32\clf\makedll>gfortran makedll1.f90 -omakedll1
> C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccWdpOGC.o:makedll1.f90:(.text+0x4bc):
> undefi
> ned reference to `LoadLibraryA@8'
> C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccWdpOGC.o:makedll1.f90:(.text+0x5d8):
> undefi
> ned reference to `GetProcAddress@12'
> collect2: ld returned 1 exit status
>
> Now the problem seems to be that gfortran is asking for 8 bytes rather
> than 4 for LoadLibrary and 12 bytes rather than 8 for GetProcAddress.
> Is this a problem with trying to account for a hidden LEN argument or
> pointer size?  Anyhow it's a bug in gfortran.  The style with -mrtd
> isn't working at all in this version, BTW.

Tobias, the person who implemented this feature, may find your post.
It may be prudent to ask on fortran @ gcc doT gnu Dot org or submit
a bug report.

--
steve


James Van Buskirk

unread,
Jul 29, 2009, 2:12:01 AM7/29/09
to
"steve" <kar...@comcast.net> wrote in message
news:0bdc9b87-f8a1-4815...@i18g2000pro.googlegroups.com...

> Tobias, the person who implemented this feature, may find your post.
> It may be prudent to ask on fortran @ gcc doT gnu Dot org or submit
> a bug report.

Well, hopefully he sees it at some point. A little testing revealed
that the assembly code is correct, only the mangled name is wrong
when there is a character argument. Perhaps the mangled name takes
into account a spurious hidden LEN parameter while the code
generator knows there is no such thing. If the argument were an
integer array instead even the mangled name is correct.

Tobias Burnus

unread,
Jul 29, 2009, 8:29:06 AM7/29/09
to
On 29 Jul., 08:12, "James Van Buskirk" <not_va...@comcast.net> wrote:
> "steve" <kar...@comcast.net> wrote in message
> news:0bdc9b87-f8a1-4815...@i18g2000pro.googlegroups.com...
> > Tobias, the person who implemented this feature, may find your post.
> > It may be prudent to ask on fortran @ gcc doT gnu Dot org or submit
> > a bug report.

It would really help if someone - James, Steve or whoever - could
submit a bugreport as reports at c.l.f might get easily lost. (Reports
at fortran@gcc can also get lost, but the chance is lower.) So far,
the number of reports is still small enough to allow for some false
positives.

> A little testing revealed
> that the assembly code is correct, only the mangled name is wrong
> when there is a character argument.  Perhaps the mangled name takes
> into account a spurious hidden LEN parameter while the code
> generator knows there is no such thing.

That's essentially what happens. There are three places which had to
be adapted for BIND(C)'s character arguments in order to have no
hidden argument:
a) The code generation of procedures
b) The code generation of the procedure call
c) The generation of external procedure declarations (i.e. of
INTERFACEs)

(a) and (b) were working, (c) wasn't. In principle, that caused only a
small inconsistency in the internal representation - except for
STDCALL on 32bit Windows as there the number of arguments enters in
the procedure name. (STDCALL on other systems such as on 32bit x86
Linux [are there such users?] would be OK as the popping of the
arguments is bound to (b) - the actual procedure call.)

I have a fix which will hopefully committed in a few hours. When it
will have reached the binaries, I do now know, however.

Thanks for the report.

Tobias

James Van Buskirk

unread,
Jul 29, 2009, 12:29:16 PM7/29/09
to
"Tobias Burnus" <bur...@net-b.de> wrote in message
news:81fd2fb2-37c1-4fd3...@c29g2000yqd.googlegroups.com...

> I have a fix which will hopefully committed in a few hours. When it
> will have reached the binaries, I do now know, however.

Probably on the weekend when http://www.equation.com recompiles.
Thanks for your prompt attention to this issue.

Looking at your patch, it seems to be saying that contained procedures
could pass by value as these ... cannot be passed as actual parameters
for a dummy procedure. I thought that f2008 was going to permit this
behavior, though.

Also ISTR that there was talk at some point of making the function
attribute behave the same as -mrtd. In the gcc manual, for example,
it says that you can specify that an individual function is called
with this calling sequence with the function attribute 'stdcall'.
So it seems to me to be desirable to upgrade gfortran's behavior
when the -mrtd switch is active to include name-mangling because
the --enable-stdcall-fixup switch mostly doesn't overcome name-
mangling problems. Maybe it's too late to fix this and another
switch like --decorate would be required. If this kind of stuff
could be achieved via compiler switches it would avoid the problem
of every function requiring one extra line of boilerplate per
compiler that the code is intended to run on.

Richard Maine

unread,
Jul 29, 2009, 2:09:11 PM7/29/09
to
James Van Buskirk <not_...@comcast.net> wrote:

> Looking at your patch, it seems to be saying that contained procedures
> could pass by value as these ... cannot be passed as actual parameters
> for a dummy procedure. I thought that f2008 was going to permit this
> behavior, though.

I'm not up to date on that in f2008. My only comment is on the
terminology.

The term "contained procedure" is not one used in the standard and its
"intuitive" definition is ambiguous. Both module procedures and internal
procedures are "contained" in that they are contained within other
scoping units after a CONTAINS statement. Yes, it matters because the
rules for module procedures and internal procedures are very different
in many ways.

I recommend against use of the term. It has no universally accepted
meaning. Some people seem to use it as a synonym for internal procedure
(which I'd guess was the idea here), while others use it to mean any
procedure that follows a CONTAINS.

Since there is already a perfectly fine, standard-defined, and
unambiguous term for internal procedure, I recommend using that term.

I could perhaps see arguments for using "contained procedure" to mean
any procedure that follows a CONTAINS, insomuch as that's the "obvious"
meaning and there is no other good single word for it. But enough people
seem to use the term differently that I'm afraid that usage still leaves
ambiguities in at least this reader's mind, and I doubt I'm alone. Heck,
for al I know, that was the meaning intended in this case and I've just
illustrated how it can be misread.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain

James Van Buskirk

unread,
Aug 3, 2009, 4:45:48 PM8/3/09
to
"James Van Buskirk" <not_...@comcast.net> wrote in message
news:h4ptd2$ded$1...@news.eternal-september.org...

> "Tobias Burnus" <bur...@net-b.de> wrote in message
> news:81fd2fb2-37c1-4fd3...@c29g2000yqd.googlegroups.com...

>> I have a fix which will hopefully committed in a few hours. When it
>> will have reached the binaries, I do now know, however.

> Probably on the weekend when http://www.equation.com recompiles.
> Thanks for your prompt attention to this issue.

OK, the version of 20090730 became available today (note: also 64-bit
version!) with some success and some failure.

C:\gcc-equation32\clf\makedll>gfortran -v
Built by Equation Solution <http://www.Equation.com>.
Using built-in specs.
Target: i386-pc-mingw32
Configured with:

../gcc-4.5-20090730-mingw/configure --host=i386-pc-mingw32 --bu
ild=x86_64-unknown-linux-gnu --target=i386-pc-mingw32 --prefix=/home/gfortran/gc
c-home/binary/mingw32/native/x86_32/gcc/4.5-20090730 --with-gcc --with-gnu-ld

--
with-gnu-as --disable-shared --disable-nls --disable-tls --with-gmp=/home/gfortr
an/gcc-home/binary/mingw32/native/x86_32/gmp --with-mpfr=/home/gfortran/gcc-home
/binary/mingw32/native/x86_32/mpfr --enable-languages=c,fortran,c++ --with-sysro

ot=/home/gfortran/gcc-home/binary/mingw32/cross/x86_32/gcc/4.5-20090730 --enable


-libgomp --enable-threads=win32 --disable-win32-registry
Thread model: win32

gcc version 4.5.0 20090730 (experimental) (GCC)

The success:

C:\gcc-equation32\clf\makedll>gfortran -Wall makedll1.f90 -omakedll1

C:\gcc-equation32\clf\makedll>makedll1


status = 0
hmodule = 000000006D5C0000

FunAddress = 000000006D5C11B4
15.833333333333334 15.833333333333339

The failure:

C:\gcc-equation32\clf\makedll>type kernel322.f90
module kernel322
implicit none
private
public LoadLibrary, GetLastError, GetProcAddress


interface
function LoadLibrary(lpFileName) bind(C,name='LoadLibraryA')
use ISO_C_BINDING
implicit none
!gcc$ ATTRIBUTES STDCALL :: LoadLibrary
integer(C_INTPTR_T) LoadLibrary
character(kind=C_CHAR) lpFileName(*)
end function LoadLibrary
function GetLastError() bind(C,name='GetLastError')
use ISO_C_BINDING
implicit none
!gcc$ ATTRIBUTES STDCALL :: GetLastError
integer(C_LONG) GetLastError
end function GetLastError
function GetProcAddress(hModule, lpProcName)
bind(C,name='GetProcAddress')

use ISO_C_BINDING
implicit none
!gcc$ ATTRIBUTES STDCALL :: GetProcAddress
type(C_FUNPTR) GetProcAddress
integer(C_INTPTR_T), value :: hModule
character(kind=C_CHAR) lpProcName(*)
end function GetProcAddress

end interface
end module kernel322

C:\gcc-equation32\clf\makedll>gfortran -Wall -c kernel322.f90

C:\gcc-equation32\clf\makedll>type makedll2.f90
program makedll
use ISO_C_BINDING
use kernel322
implicit none
interface

C:\gcc-equation32\clf\makedll>gfortran -Wall makedll2.f90
kernel322.o -omakedll2

Warning: resolving _GetProcAddress by linking to _GetProcAddress@8
Use --enable-stdcall-fixup to disable these warnings
Use --disable-stdcall-fixup to disable these fixups

C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\cc8dGM0E.o:makedll2.f90:(.text+0x4bc):
undefi
ned reference to `LoadLibraryA'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\cc8dGM0E.o:makedll2.f90:(.text+0x4c4):
undefi
ned reference to `GetLastError'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\cc8dGM0E.o:makedll2.f90:(.text+0x5dd):
undefi
ned reference to `GetLastError'


collect2: ld returned 1 exit status

So the !gcc$ ATTRIBUTES stuff doesn't seem to be propagating via
USE association. Let me add one more item to my wish list, and I
think this would be fairly easy and extremely useful:

C:\gcc-equation32\clf\makedll>type kernel323.f90
module kernel323
implicit none
private
public LoadLibrary, GetLastError, GetProcAddress


interface
function LoadLibrary(lpFileName) bind(C,name='LoadLibraryA')
use ISO_C_BINDING
implicit none

integer(C_INTPTR_T) LoadLibrary
character(kind=C_CHAR) lpFileName(*)
end function LoadLibrary
function GetLastError() bind(C,name='GetLastError')
use ISO_C_BINDING
implicit none

integer(C_LONG) GetLastError
end function GetLastError
function GetProcAddress(hModule, lpProcName)
bind(C,name='GetProcAddress')

use ISO_C_BINDING
implicit none


type(C_FUNPTR) GetProcAddress
integer(C_INTPTR_T), value :: hModule
character(kind=C_CHAR) lpProcName(*)
end function GetProcAddress

end interface
end module kernel323

C:\gcc-equation32\clf\makedll>gfortran -Wall -c -mrtd kernel323.f90

C:\gcc-equation32\clf\makedll>type makedll3.f90
program makedll
use ISO_C_BINDING
use kernel323
implicit none
interface

C:\gcc-equation32\clf\makedll>gfortran -Wall makedll3.f90
kernel323.o -omakedll3

Warning: resolving _GetProcAddress by linking to _GetProcAddress@8
Use --enable-stdcall-fixup to disable these warnings
Use --disable-stdcall-fixup to disable these fixups

C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\cccQurLe.o:makedll3.f90:(.text+0x4bc):
undefi
ned reference to `LoadLibraryA'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\cccQurLe.o:makedll3.f90:(.text+0x4c4):
undefi
ned reference to `GetLastError'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\cccQurLe.o:makedll3.f90:(.text+0x5dd):
undefi
ned reference to `GetLastError'


collect2: ld returned 1 exit status

I really think getting the kernel323.f90/makedll3.f90 example above
to work would get gfortran over the hump as far as the Win32 API
stuff goes. In the example, not only am I counting on the !gcc$
ATTRIBUTES stuff to propagate via USE association, but to have the
appropriate !gcc$ ATTRIBUTE to be set via the -mrtd switch. This
would allow writing modules full of interface blocks that wouldn't
be cluttered with per-compiler Directive Enhanced Compilation junk.
There is a lot of stuff IMHO that would work (or be close to
working: I haven't done any testing with ABSTRACT INTERFACE yet)
across platforms, like opengl and java, not just the obvious
symmetry between 32- and 64-bit Windows that is tested in the
example.

Tobias Burnus

unread,
Aug 4, 2009, 5:30:39 AM8/4/09
to
On 3 Aug., 16:45, "James Van Buskirk" <not_va...@comcast.net> wrote:
> OK, the version of 20090730 became available today (note: also 64-bit
> version!) with some success and some failure.

Thanks for testing.

> So the !gcc$ ATTRIBUTES stuff doesn't seem to be propagating via
> USE association.

That should be fixed now. There is really a lack of gfortran
developers under Windows, unfortunately. That makes testing more
difficult and also the inclusion of special features for Windows
slower.


> Let me add one more item to my wish list, and I
> think this would be fairly easy and extremely useful:

[...]


>    interface
>       function LoadLibrary(lpFileName) bind(C,name='LoadLibraryA')
>          use ISO_C_BINDING
>          implicit none
>          integer(C_INTPTR_T) LoadLibrary
>          character(kind=C_CHAR) lpFileName(*)

> C:\gcc-equation32\clf\makedll>gfortran -Wall -c -mrtd kernel323.f90


> C:\gcc-equation32\clf\makedll>gfortran -Wall makedll3.f90
> kernel323.o -omakedll3
>
> Warning: resolving _GetProcAddress by linking to _GetProcAddress@8

[...]


> I really think getting the kernel323.f90/makedll3.f90 example above
> to work would get gfortran over the hump as far as the Win32 API
> stuff goes.  In the example, not only am I counting on the !gcc$
> ATTRIBUTES stuff to propagate via USE association, but to have the
> appropriate !gcc$ ATTRIBUTE to be set via the -mrtd switch.  This
> would allow writing modules full of interface blocks that wouldn't
> be cluttered with per-compiler Directive Enhanced Compilation junk.

The -mrtd switch is a general GCC switch. I do not understand why
the @<n> is not added automatically, but I somehow feels wrong to
add automatically the @<n> decoration for Fortran but not for C.

Additionally, I think you may run into trouble with -mrtd as this
converts all procedure calls, including those of the intrinsics
(acos, matmul, ...) and of open, write etc. I am not sure, but I
fear that using -mrtd you are leaving the arguments on the stack
and will run out of stack memory at some point: When calling
"matmul" the caller won't free the stack due to -mrtd (STDCALL)
while the matmul function in the gfortran run-time library won't
free it as it uses CDECL calling convention. One could fix this
by adding "ATTRIBUTE CDECL :: matmul" etc., but then it is easier
to add a few "!GCC$" directives. Under C, the windows.h contains
the STDCALL macro (or __STDCALL?, I do not remember). For Win64
one could simply expand it to nothing. You could do something
similar in Fortran:

For Win32:
# define STDCALL stdcall
For Win64
# define STDCALL cdecl

!GCC$ ATTRIBUTE STDCALL :: ...


> There is a lot of stuff IMHO that would work (or be close to
> working: I haven't done any testing with ABSTRACT INTERFACE yet)
> across platforms, like opengl and java, not just the obvious
> symmetry between 32- and 64-bit Windows that is tested in the
> example.

In any case: Thanks for testing! I think there might be still bugs
lurking. Actually, ABSTRACT INTERFACE could be exactly something which
fails as there was a bug in the attribute copying routine. I will send
another patch.

Tobias

James Van Buskirk

unread,
Aug 15, 2009, 5:28:36 PM8/15/09
to
"Tobias Burnus" <bur...@net-b.de> wrote in message
news:f0a3c852-5b6f-4987...@s31g2000yqs.googlegroups.com...

On 3 Aug., 16:45, "James Van Buskirk" <not_va...@comcast.net> wrote:

> > So the !gcc$ ATTRIBUTES stuff doesn't seem to be propagating via
> > USE association.

> That should be fixed now. There is really a lack of gfortran
> developers under Windows, unfortunately. That makes testing more
> difficult and also the inclusion of special features for Windows
> slower.

OK, let's repeat my failing test with this week's snapshot:

C:\gcc_equation32\clf\makedll>gcc -v


Built by Equation Solution <http://www.Equation.com>.
Using built-in specs.
Target: i386-pc-mingw32
Configured with:

../gcc-4.5-20090813-mingw/configure --host=i386-pc-mingw32 --bu
ild=x86_64-unknown-linux-gnu --target=i386-pc-mingw32 --prefix=/home/gfortran/gc
c-home/binary/mingw32/native/x86_32/gcc/4.5-20090813 --with-gcc --with-gnu-ld

--
with-gnu-as --disable-shared --disable-nls --disable-tls --with-gmp=/home/gfortr
an/gcc-home/binary/mingw32/native/x86_32/gmp --with-mpfr=/home/gfortran/gcc-home
/binary/mingw32/native/x86_32/mpfr --enable-languages=c,fortran,c++ --with-sysro

ot=/home/gfortran/gcc-home/binary/mingw32/cross/x86_32/gcc/4.5-20090813 --enable


-libgomp --enable-threads=win32 --disable-win32-registry
Thread model: win32

gcc version 4.5.0 20090813 (experimental) (GCC)

C:\gcc_equation32\clf\makedll>type kernel322.f90


module kernel322
implicit none
private
public LoadLibrary, GetLastError, GetProcAddress

interface
function LoadLibrary(lpFileName) bind(C,name='LoadLibraryA')
use ISO_C_BINDING
implicit none

!gcc$ ATTRIBUTES STDCALL :: LoadLibrary
integer(C_INTPTR_T) LoadLibrary
character(kind=C_CHAR) lpFileName(*)
end function LoadLibrary

function GetLastError() bind(C,name='GetLastError')
use ISO_C_BINDING
implicit none


!gcc$ ATTRIBUTES STDCALL :: GetLastError
integer(C_LONG) GetLastError
end function GetLastError
function GetProcAddress(hModule, lpProcName)

bind(C,name='GetProcAddress')

use ISO_C_BINDING
implicit none


!gcc$ ATTRIBUTES STDCALL :: GetProcAddress
type(C_FUNPTR) GetProcAddress
integer(C_INTPTR_T), value :: hModule
character(kind=C_CHAR) lpProcName(*)
end function GetProcAddress
end interface
end module kernel322

C:\gcc_equation32\clf\makedll>gfortran -Wall -c kernel322.f90

C:\gcc_equation32\clf\makedll>type makedll2.f90

C:\gcc_equation32\clf\makedll>gfortran -Wall makedll2.f90 -omakedll2

C:\gcc_equation32\clf\makedll>makedll2


status = 0
hmodule = 000000006D5C0000
FunAddress = 000000006D5C11B4
15.833333333333334 15.833333333333339

So congratulations are in order, as you seem to have made it go
despite limited opportunities for testing.

Now, I am not sure that I follow this statement. I haven't tested
this statement recently, but my recollection is that it's not true.
Why doesn't the negation of -mrtd (the default) canovert all procedure
calls to CDECL? These switches shouldn't override !gcc$ annotations
nor should they override the information the compiler can get from
explicit interfaces acquired via USE association or because the
procedure is intrinsic. If you are sure about this issue, I could
make up some test cases you could use as a basis for some bug reports.
If you are not so sure maybe you could have another look as it's a
bit tricky to compose good test cases for this kind of problem.

> I am not sure, but I
> fear that using -mrtd you are leaving the arguments on the stack
> and will run out of stack memory at some point: When calling
> "matmul" the caller won't free the stack due to -mrtd (STDCALL)
> while the matmul function in the gfortran run-time library won't
> free it as it uses CDECL calling convention. One could fix this
> by adding "ATTRIBUTE CDECL :: matmul" etc., but then it is easier
> to add a few "!GCC$" directives. Under C, the windows.h contains
> the STDCALL macro (or __STDCALL?, I do not remember). For Win64
> one could simply expand it to nothing. You could do something
> similar in Fortran:

> For Win32:
> # define STDCALL stdcall
> For Win64
> # define STDCALL cdecl

> !GCC$ ATTRIBUTE STDCALL :: ...

Horrors! To begin with, STDCALL is perfectly well defined in
Win64, and defined to be the same as CDECL. So this stuff shouldn't
be necessary under Win64. Let's try this right now:

C:\gfortran\clf\makedll>gfortran -v


Built by Equation Solution <http://www.Equation.com>.
Using built-in specs.

Target: x86_64-pc-mingw32
Configured with:
../gcc-4.5-20090813-mingw/configure --host=x86_64-pc-mingw32 --
build=x86_64-unknown-linux-gnu --target=x86_64-pc-mingw32 --prefix=/home/gfortra
n/gcc-home/binary/mingw32/native/x86_64/gcc/4.5-20090813 --with-gmp=/home/gfortr
an/gcc-home/binary/mingw32/native/x86_64/gmp --with-mpfr=/home/gfortran/gcc-home
/binary/mingw32/native/x86_64/mpfr --with-sysroot=/home/gfortran/gcc-home/binary
/mingw32/cross/x86_64/gcc/4.5-20090813 --with-gcc --with-gnu-ld --with-gnu-as
--
disable-shared --disable-nls --disable-tls --enable-libgomp --enable-languages=c
,fortran,c++ --enable-threads=win32 --disable-win32-registry
Thread model: win32
gcc version 4.5.0 20090813 (experimental) (GCC)

C:\gfortran\clf\makedll>gfortran -Wall -c kernel322.f90

C:\gfortran\clf\makedll>gfortran -Wall makedll2.f90 kernel322.o -omakedll2

C:\gfortran\clf\makedll>makedll2


status = 0
hmodule = 000000006D5C0000

FunAddress = 000000006D5C1420
15.833333333333332 15.833333333333341

Furthermore, using the C preprocessor is in my view to be avoided
because it's unreliable and unpredictable, at least in the hands of a
Fortran programmer such as myself. As I see it, there are now two
incompatible extensions: -mrtd that sets STDCALL and !gcc$ attributes
STDCALL that does this and additionally mangles names. Presently
if you want to get STDCALL and not mangle names, you have to use
-mrtd (via the command line) and if you want to set STDCALL plus
mangled names, you have to use !gcc$ attributes STDCALL. This seems
to me a bit awkward to have to explain, and the explanation would
have to be duplicated in both places in the documentation. If you
want both options to be available for gfortran, it seems to me to be
cleaner to make a new command line option for gfortran as well as
another !gcc$ ATTRIBUTE so that the full choice could be made in
either place. The present kind of bric-a-brac seems to me to have
the potential to cause serious confusion for anyone the first time
he tries to achieve STDCALL programming in gfortran.

> > There is a lot of stuff IMHO that would work (or be close to
> > working: I haven't done any testing with ABSTRACT INTERFACE yet)
> > across platforms, like opengl and java, not just the obvious
> > symmetry between 32- and 64-bit Windows that is tested in the
> > example.

> In any case: Thanks for testing! I think there might be still bugs
> lurking. Actually, ABSTRACT INTERFACE could be exactly something which
> fails as there was a bug in the attribute copying routine. I will send
> another patch.

OK, I have seen the struggles you have had with this over the last
two weeks. My concept regarding ABSTRACT INTERFACE is rather long-
winded though, and I don't have anything ready just yet. If I can make
the time I would like to test...

James Van Buskirk

unread,
Aug 16, 2009, 4:43:09 AM8/16/09
to
"James Van Buskirk" <not_...@comcast.net> wrote in message
news:h679a8$db3$1...@news.eternal-september.org...

> If you
> want both options to be available for gfortran, it seems to me to be
> cleaner to make a new command line option for gfortran as well as
> another !gcc$ ATTRIBUTE so that the full choice could be made in
> either place. The present kind of bric-a-brac seems to me to have
> the potential to cause serious confusion for anyone the first time
> he tries to achieve STDCALL programming in gfortran.

And you may need both options. It's starting to look like jni doesn't
want name mangling, but Win32 API does :( If I can ever get a jni
example to survive to some sort of output I may be able to verify this
assumption.

Tobias Burnus

unread,
Aug 16, 2009, 7:33:04 AM8/16/09
to
Hi James,

thanks for testing.

The -mrtd does not override the settings done via "__attribute__
((..))" under C/C++ nor the ones done via "!gcc$ attribute", but it
changes the default. Without -mrtd, the default is CDECL, with -mrtd
it is STDCALL. All (C/C++) functions and (Fortran) procedures without
any *explicit* CDECL/STDCALL/FASTCALL attribute use cdecl (default) or
stdcall (with -mrtd).

For details see the manual: For M680x0 and ColdFire processors at
http://gcc.gnu.org/onlinedocs/gcc/M680x0-Options.html, for the more
common processors of the i386 and x86-64 family, one fonds it at
http://gcc.gnu.org/onlinedocs/gcc/i386-and-x86_002d64-Options.html#index-mrtd-1292
(and for other platforms this option does not exist):

"Use a different function-calling convention, in which functions that
take a fixed number of arguments return with the ret num instruction,
which pops their arguments while returning. This saves one instruction
in the caller since there is no need to pop the arguments there.
You can specify that an individual function is called with this
calling sequence with the function attribute `stdcall'. You can also
override the -mrtd option by using the function attribute `cdecl'."


> > For Win32:
> > # define STDCALL stdcall
> > For Win64
> > # define STDCALL cdecl
> > !GCC$ ATTRIBUTE STDCALL :: ...
>
> Horrors!   To begin with, STDCALL is perfectly well defined in
> Win64, and defined to be the same as CDECL.

Do you mean the attribute, the effect, the ABI definition or
windows.h? At least in the sense that the callee pops the arguments
from the stack, STDCALL is not used by the x86-64-Windows DLLs. How
the STDCALL attribute is handled, is something different. For instance
on x86-64 Linux, using the STDCALL attribute with GCC (C,
Fortran, ...) gives a compile-time warning that the argument is
ignored.

What Microsoft defined in their ABI and how MinGW64/Cygwin64 handle it
(or more precisely the Window64 target code of GCC), I do no know.


> As I see it, there are now two
> incompatible extensions: -mrtd that sets STDCALL and !gcc$ attributes
> STDCALL that does this and additionally mangles names.  Presently
> if you want to get STDCALL and not mangle names, you have to use
> -mrtd (via the command line) and if you want to set STDCALL plus
> mangled names, you have to use !gcc$ attributes STDCALL.  This seems
> to me a bit awkward to have to explain, and the explanation would
> have to be duplicated in both places in the documentation.

That is not completely true: The stdcall attribute does not always
mangle the name - it only does so on Windows, but not on, e.g., Linux.

If I understood it correctly, with GCC on Windows the @<n> mangling
happens only for __attribute__((stdcall)) / "!GCC$ attribute stdcall"
and neither for "-mrtd" nor for __attribute__((alias("someName"))) [no
gfortran equivalent, yet]. I find that rather confusing, but that's
how MinGW32/Cygwin handled it since years.

From the gfortran side, we are agnostic how the middle-end/target part
handle it. We just set the appropriate attribute and call a function
which mangles the name - that depends on the machine-specific (-m...)
options, the attributes, and the system for which one is compiling.

> If you
> want both options to be available for gfortran, it seems to me to be
> cleaner to make a new command line option for gfortran as well as
> another !gcc$ ATTRIBUTE so that the full choice could be made in
> either place.  The present kind of bric-a-brac seems to me to have
> the potential to cause serious confusion for anyone the first time
> he tries to achieve STDCALL programming in gfortran.

Well, that's the same situation for C. My impression is, however, that
almost no one uses -mrtd and that since STDCALL is defined in all the
Windows .h files there are fewer issues.

My advice is: Use "GNU$ ATTRIBUTE stdcall" were needed and do not
touch -mrtd.

The problem with -mrtd is also:

"Warning: this calling convention is incompatible with the one
normally used on Unix, so you cannot use it if you need to call
libraries compiled with the Unix compiler.
Also, you must provide function prototypes for all functions that take
variable numbers of arguments (including printf); otherwise incorrect
code will be generated for calls to those functions.
In addition, seriously incorrect code will result if you call a
function with too many arguments. (Normally, extra arguments are
harmlessly ignored.)"

My feeling is that you will get problems with calls to
libgfortran.dll: The library has been compiled without -mrtd - and it
also cannot be compiled with it as some C functions in it take a
variable number of arguments. And as they are not explicitly marked as
"cdecl": when compiling a file with -mrtd, also calls to the library
use stdcall. That might look as if it is working, but as neither the
caller nor the callee cleans up the stack, you may run into problems
with larger programs. Thus: Avoid -mrtd - and mark the few(?) Windows
API calls as STDCALL.


[Regarding "@<n>" decoration of procedure names]


> And you may need both options. It's starting to look like jni doesn't
> want name mangling, but Win32 API does :( If I can ever get a jni
> example to survive to some sort of output I may be able to verify this
> assumption.

How is it handled with C/C++? I currently do not see the possibility
to declare a prototype in C to use stdcall while at the same time
prevent the "@<n>" name mangling. But I might have missed some
possibility.

Tobias

James Van Buskirk

unread,
Aug 16, 2009, 12:27:13 PM8/16/09
to
"Tobias Burnus" <bur...@net-b.de> wrote in message
news:52428019-ef2f-4263...@w6g2000yqw.googlegroups.com...

> The -mrtd does not override the settings done via "__attribute__
> ((..))" under C/C++ nor the ones done via "!gcc$ attribute", but it
> changes the default. Without -mrtd, the default is CDECL, with -mrtd
> it is STDCALL. All (C/C++) functions and (Fortran) procedures without
> any *explicit* CDECL/STDCALL/FASTCALL attribute use cdecl (default) or
> stdcall (with -mrtd).

I have had a hard time understanding this because it seems to me
simply to be wrong. In math.h, acos is declared as:

_CRTIMP double __cdecl acos (double);

So any C function that uses it is going to have the -mrtd overridden.
The _CRTIMP macro seems to make it dllimport as well. I would have
thought that Fortran would set up its intrinsics so that you could
use them just as in C, where the overrride is already in place. My
example shows otherwise:

C:\gcc_equation32\clf\stdcall_test>type test_acos.f90
program main
implicit none
double precision test_acos, x, y
integer n

x = 0.123456789d0
n = 20
write(*,*) 'Invoking test_acos'
y = test_acos(x,n)
write(*,*) 'Back from test_acos'
write(*,*) 'y = ', y
end program main

function test_acos(x,n)
implicit none
double precision x, y, test_acos
intrinsic acos
!gcc$ attributes cdecl :: acos
integer n, i

test_acos = 0
y = x
do i = 1, n
test_acos = test_acos+acos(y)
y = (y+1)/2
end do
end function test_acos

C:\gcc_equation32\clf\stdcall_test>gfortran -Wall -fomit-frame-pointer
test_acos
.f90 -otest_acos

C:\gcc_equation32\clf\stdcall_test>test_acos
Invoking test_acos
Back from test_acos
y = 4.6966838489214204

C:\gcc_equation32\clf\stdcall_test>gfortran -Wall -mrtd -fomit-frame-pointer
tes
t_acos.f90 -otest_acos

C:\gcc_equation32\clf\stdcall_test>test_acos

Now, in this last instance, Windows asks me if I want to send an error
report to Microsoft because test_acos.exe has encountered a problem
and needs to close. Note that I even explicitly overrode -mrtd with
the cdecl attribute but it didn't do any good. Examination of
assembly language output confirms that gfortran is setting up a
stdcall invocation of acos. Actually the program doesn't even survive
long enough to test this because the output of the first write statement
doesn't appear on the screen.

Now, another issue is whether !gcc$ attributes apply to generic
functions or just a specific version. I tried changing acos to
dacos and got the same results.

Maybe the situation is as bad as you indicate.

Craig Powers

unread,
Aug 17, 2009, 1:51:44 PM8/17/09
to

At least within the Microsoft family of compilers, there are ways to
override this outside of the source itself---I suspect this comes in via
the linker, so it may also apply to gcc, at least in the case of mingw.
I forget the name of the auxiliary file, but it provides information
on how a library should be organized with respect to exports.

Craig Powers

unread,
Aug 17, 2009, 1:53:50 PM8/17/09
to

At least within the Microsoft family of compilers, there are ways to

0 new messages