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

beep in Windows XP x64

111 views
Skip to first unread message

vitro

unread,
Jan 12, 2009, 4:35:28 AM1/12/09
to
I wonder how to create a beep to remind the completion of program
under 64 bit system. It seems char(7) does not work in 64 bit system.
I am working on a Dell Workstation with Xeon CPUs. My compilers are 64
bit gfortran v4.4 and/or 32 bit CVF v6.6. Or how to create other kinds
of sound, e.g. calling wav files? Sorry for my poor knowledge in
Fortran and computer science.
Your help will be highly appreciated.

Vitro

James Van Buskirk

unread,
Jan 12, 2009, 11:54:56 AM1/12/09
to
"vitro" <iam...@gmail.com> wrote in message
news:f8d9c872-c499-437e...@h41g2000yqn.googlegroups.com...

C:\gfortran\clf\beep>type beep.f90
module winapi
use ISO_C_BINDING
implicit none
private
integer, parameter, public :: MB_ICONASTERISK = int(Z'00000040', C_LONG)
integer, parameter, public :: MB_ICONEXCLAMATION = int(Z'00000030',
C_LONG)
integer, parameter, public :: MB_ICONHAND = int(Z'00000010', C_LONG)
integer, parameter, public :: MB_ICONQUESTION = int(Z'00000020', C_LONG)
integer, parameter, public :: MB_OK = int(Z'00000000', C_LONG)
public MessageBeep
interface
function MessageBeep(uType) bind(C,name='MessageBeep')
use ISO_C_BINDING
implicit none
integer(C_INT), value :: uType
integer(C_INT) MessageBeep
end function MessageBeep
end interface
end module winapi

program beep
use winapi
use ISO_C_BINDING, only: C_INT
implicit none
integer(C_INT) result

result = MessageBeep(MB_OK)
end program beep

C:\gfortran\clf\beep>gfortran beep.f90 -obeep

C:\gfortran\clf\beep>beep
<Makes beep sound>

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


user1

unread,
Jan 12, 2009, 12:59:49 PM1/12/09
to

Gotta love Windows. The above is so much simpler than

write(*,*) char(7)


Steve Lionel

unread,
Jan 12, 2009, 4:54:04 PM1/12/09
to
On Mon, 12 Jan 2009 09:54:56 -0700, "James Van Buskirk"
<not_...@comcast.net> wrote:

> interface
> function MessageBeep(uType) bind(C,name='MessageBeep')
> use ISO_C_BINDING
> implicit none
> integer(C_INT), value :: uType
> integer(C_INT) MessageBeep
> end function MessageBeep
> end interface

I'm somewhat astonished that this works in gfortran, as the Win32 API routine
MessageBeep has a STDCALL interface. Maybe you tried this on an x64 system?
It would not work at all in CVF because of the use of the C interoperability
features that CVF does not support.

The CVF program could be this:

use dfwin
i = MessageBeep(-1)
end

but:

write (*,*) char(7)

works too.
--
Steve Lionel
Developer Products Division
Intel Corporation
Nashua, NH

For email address, replace "invalid" with "com"

User communities for Intel Software Development Products
http://software.intel.com/en-us/forums/
Intel Fortran Support
http://support.intel.com/support/performancetools/fortran
My Fortran blog
http://www.intel.com/software/drfortran

e p chandler

unread,
Jan 12, 2009, 5:08:16 PM1/12/09
to
On Jan 12, 4:54 pm, Steve Lionel <Steve.Lio...@intel.invalid> wrote:
> On Mon, 12 Jan 2009 09:54:56 -0700, "James Van Buskirk"
>
> <not_va...@comcast.net> wrote:
> >   interface
> >      function MessageBeep(uType) bind(C,name='MessageBeep')
> >         use ISO_C_BINDING
> >         implicit none
> >         integer(C_INT), value :: uType
> >         integer(C_INT) MessageBeep
> >      end function MessageBeep
> >   end interface
>
> I'm somewhat astonished that this works in gfortran, as the Win32 API routine
> MessageBeep has a STDCALL interface.  Maybe you tried this on an x64 system?

I'll bet money on that! IIRC his system and gfortran is 64 bits.

[snip]

jfh

unread,
Jan 12, 2009, 8:24:06 PM1/12/09
to
On Jan 13, 10:54 am, Steve Lionel <Steve.Lio...@intel.invalid> wrote:
> On Mon, 12 Jan 2009 09:54:56 -0700, "James Van Buskirk"
>

Steve's one-liner, in which I changed char(7) to achar(7) to enforce
ASCII, duly beeps on our linux system with g95, Sun f95 and ifort, but
it doesn't with gfortran even though it seems to be valid Fortran 95.
However our systems people, not I, update that, so our gfortran may be
too old to treat achar(7) correctly. The gfortran -v command said
among other things
Target: i386-redhat-linux5E
Thread model: posix
gcc version 4.1.2 20071124 (Red Hat 4.1.2-42)

John Harper

James Van Buskirk

unread,
Jan 12, 2009, 10:21:20 PM1/12/09
to
"e p chandler" <ep...@juno.com> wrote in message
news:03d11ef7-d95e-4371...@i20g2000prf.googlegroups.com...

Yes. Also the subject line gives it away. Unfortunately, although
it would likely take a one-line fix to make gfortran work like g95
does on 32-bit Windows, where one can write:

function MessageBeep(uType) bind(C,name='MessageBeep@4')

in gfortran one gets the error message:

Invalid C name in NAME= specifier at (1)

Why can't that be fixed simply by continuing rather than checking
for validity?

Similarly gfortran on 64-bit Windows has a bug which renders
it alomost unusable: at one point in formatting floating point
numbers for output it compares with Z'10' rather than 10 so
that sometimes you get .00: instead of .010 or .00? instead of
.015 so that any large enough block of numerical output will
be garbage. Again should be a one-line fix and is even OK
in the www.equation.com builds, but the latter builds don't
incorporate bug fixes to Mingw 64, at least not in a timely
manner.

e p chandler

unread,
Jan 13, 2009, 2:14:08 AM1/13/09
to
On Jan 12, 10:21 pm, "James Van Buskirk" <not_va...@comcast.net>
wrote:
> "e p chandler" <e...@juno.com> wrote in messagenews:03d11ef7-d95e-4371...@i20g2000prf.googlegroups.com...

> > On Jan 12, 4:54 pm, Steve Lionel <Steve.Lio...@intel.invalid> wrote:
> > > On Mon, 12 Jan 2009 09:54:56 -0700, "James Van Buskirk"
> > > <not_va...@comcast.net> wrote:
> > > > interface
> > > > function MessageBeep(uType) bind(C,name='MessageBeep')
> > > > use ISO_C_BINDING
> > > > implicit none
> > > > integer(C_INT), value :: uType
> > > > integer(C_INT) MessageBeep
> > > > end function MessageBeep
> > > > end interface
> > > I'm somewhat astonished that this works in gfortran, as the Win32 API
> > > routine
> > > MessageBeep has a STDCALL interface. Maybe you tried this on an x64
> > > system?
> > I'll bet money on that! IIRC his system and gfortran is 64 bits.
>
> Yes.  Also the subject line gives it away.  Unfortunately, although
> it would likely take a one-line fix to make gfortran work like g95
> does on 32-bit Windows, where one can write:
>
> function MessageBeep(uType) bind(C,name='MessageBeep@4')
>
> in gfortran one gets the error message:
>
> Invalid C name in NAME= specifier at (1)

[snip]

OK. Now I'm mystified. Your program does compile and run on Win32
(Vista SP1), MinGW (4.1) g95, compiled with

g95 beep.f90

Bear in mind that I don't use (or understand) C interoperability. How
does this program deal with the calling convention on Win32 which
Steve Lionel points out is STDCALL for 'MessageBeep@4'. I see that
name is extended to take care of the name mangling, but what about the
stack? (RET vs RET 4)?

-- Elliot

James Van Buskirk

unread,
Jan 13, 2009, 2:29:59 AM1/13/09
to
"e p chandler" <ep...@juno.com> wrote in message
news:8fb7b5b5-1dbc-423a...@s1g2000prg.googlegroups.com...

> > > > > function MessageBeep(uType) bind(C,name='MessageBeep')

> > function MessageBeep(uType) bind(C,name='MessageBeep@4')

> OK. Now I'm mystified. Your program does compile and run on Win32


> (Vista SP1), MinGW (4.1) g95, compiled with

> g95 beep.f90

> Bear in mind that I don't use (or understand) C interoperability. How
> does this program deal with the calling convention on Win32 which
> Steve Lionel points out is STDCALL for 'MessageBeep@4'. I see that
> name is extended to take care of the name mangling, but what about the
> stack? (RET vs RET 4)?

Did you try the first version above or the second? Were there any
warning messages from g95? Please try out the following version
(untested):

module winapi
use ISO_C_BINDING
implicit none
private

integer, parameter, public :: MB_OK = int(Z'00000000', C_LONG)
public MessageBeep

interface
function MessageBeep(uType) bind(C,name='MessageBeep')
use ISO_C_BINDING
implicit none
integer(C_INT), value :: uType
integer(C_INT) MessageBeep
end function MessageBeep
end interface

end module winapi

program beep
implicit none
external sub
integer n

n = 20
write(*,*) 'Calling sub'
call sub(n)
write(*,*) 'Returning from sub'
end program beep

subroutine sub(n)


use winapi
use ISO_C_BINDING, only: C_INT
implicit none
integer(C_INT) result

integer n
integer i

do i = 1, n
result = MessageBeep(MB_OK)
end do
end subroutine sub

e p chandler

unread,
Jan 13, 2009, 4:50:17 AM1/13/09
to
On Jan 13, 2:29 am, "James Van Buskirk" <not_va...@comcast.net> wrote:
> "e p chandler" <e...@juno.com> wrote in messagenews:8fb7b5b5-1dbc-423a...@s1g2000prg.googlegroups.com...

>
> > > > > > function MessageBeep(uType) bind(C,name='MessageBeep')
> > > function MessageBeep(uType) bind(C,name='MessageBeep@4')
> > OK. Now I'm mystified. Your program does compile and run on Win32
> > (Vista SP1), MinGW (4.1) g95, compiled with
> > g95 beep.f90
> > Bear in mind that I don't use (or understand) C interoperability. How
> > does this program deal with the calling convention on Win32 which
> > Steve Lionel points out is STDCALL for 'MessageBeep@4'. I see that
> > name is extended to take care of the name mangling, but what about the
> > stack? (RET vs RET 4)?
>
> Did you try the first version above or the second?  Were there any
> warning messages from g95?

The second which used 'MessageBeep@4'. No warnings.

C:\Users\epc\temp>g95 -v
...
Thread model: win32
gcc version 4.1.2 (g95 0.92!) Dec 25 2008

C:\Users\epc\temp>g95 beep1.f90
C:\Users\epc\AppData\Local\Temp/cc61Btis.o:beep1.f90:(.text+0x128):
undefined re
ference to `_MessageBeep'

C:\Users\epc\temp>fc beep1.f90 beep2.f90
Comparing files beep1.f90 and BEEP2.F90
***** beep1.f90


interface
function MessageBeep(uType) bind(C,name='MessageBeep')
use ISO_C_BINDING

***** BEEP2.F90
interface


function MessageBeep(uType) bind(C,name='MessageBeep@4')

use ISO_C_BINDING
*****


C:\Users\epc\temp>g95 beep2.f90

C:\Users\epc\temp>a
Calling sub

--> Dialog Box "a.exe has stopped working"
--> Dialog Box "virus warning"

C:\Users\epc\temp>

Terence

unread,
Jan 13, 2009, 5:57:15 AM1/13/09
to

I needed an integer*2 version and this works for me with CVF 6.6c

SUBROUTINE BEEP(IFREQ,IDUR)
! Integer*2 version of BEEPQQ
USE DFLIB
IMPLICIT NONE
INTEGER*2,INTENT(IN) :: IFREQ,IDUR
INTEGER*4 :: JFREQ,JDUR
JFREQ=IFREQ
JDUR=IDUR
IF (JFREQ.LE.0) JFREQ=440
IF (JDUR .LE.0) JDUR =200
CALL BEEPQQ(JFREQ,JDUR)
END SUBROUTINE BEEP

Steve Lionel

unread,
Jan 13, 2009, 10:27:27 AM1/13/09
to
On Mon, 12 Jan 2009 20:21:20 -0700, "James Van Buskirk"
<not_...@comcast.net> wrote:

>> I'll bet money on that! IIRC his system and gfortran is 64 bits.
>
>Yes. Also the subject line gives it away. Unfortunately, although
>it would likely take a one-line fix to make gfortran work like g95
>does on 32-bit Windows, where one can write:
>
>function MessageBeep(uType) bind(C,name='MessageBeep@4')
>
>in gfortran one gets the error message:
>
>Invalid C name in NAME= specifier at (1)
>
>Why can't that be fixed simply by continuing rather than checking
>for validity?

I had missed the x64 in the subject line, but the OP's wanting CVF as well
meant that IA-32 issues were still valid.

I would not expect adding @4 to work in the NAME= specifier. This is to give
the name as it would be written in C, not the fully decorated name (which also
has a leading underscore). The compiler is expected to add any decoration
that the "companion C processor" would. Even if you succeeded here, you also
need to get the compiler to use STDCALL semantics so that the stack doesn't
get popped twice.

Given that the default behavior (in absence of /Gm, etc.) of C compilers on
IA-32 Windows is to use the C mechanism, there is no standard-conforming way
to specify STDCALL and you'll need to resort to extensions.

I'll comment that writing CHAR(7) (or ACHAR(7) works only if you've got a
console application, whereas calling MessageBeep will work for any application
type.
--


Steve Lionel
Developer Products Division

James Van Buskirk

unread,
Jan 13, 2009, 12:02:13 PM1/13/09
to
"e p chandler" <ep...@juno.com> wrote in message
news:ecd66d7a-4e64-4bfa...@a29g2000pra.googlegroups.com...

> C:\Users\epc\temp>g95 beep2.f90

> C:\Users\epc\temp>a
> Calling sub

> --> Dialog Box "a.exe has stopped working"
> --> Dialog Box "virus warning"

Ah, success! My point was that a procedure could have a prolog like:

push ebp
mov ebp, esp
sub esp, 40; create stack frame

and then an epilog such as:

mov esp, ebp
pop ebp
ret

So that if nothing completely fatal happened to esp in the interim
the program could recover from forgetting exactly where esp was
supposed to point at. The point of beep2.f90 was that after 19
ill-matched invocations of _MessageBeep@4, the stack has been
backed up by 76 bytes so that the stack frame of subroutine sub
has likely been exhausted. During execution of the _MessageBeep@4
the 20th time (or earlier) the return address on the stack that
subroutine sub needs to return to program beep will then have been
overwritten, so it will try to return to some random place, just
like a buffer overrun exploit tries to do. The OS will, unless
you are very unlucky, bust this kind of behavior.

To fix this, try compiling with:

g95 -mrtd beep2.f90

Now the call to _MessageBeep@4 should go through without a hitch.

vitro

unread,
Jan 13, 2009, 12:23:47 PM1/13/09
to
Thank you for all of your replies.
Jame's first code and that with "calling sub" work on my 64 bit
gfortran under x64. That with @4 does not. This gfortran is the Win64
build from GNU wiki site currently.
Steve's MessageBeep of Win32 APIs also works.
I think probably the fundamental answer to my question is there is no
built-in speaker in this workstation. That's why char(7) does not
sound at all. Right?

Steve Lionel

unread,
Jan 13, 2009, 1:39:42 PM1/13/09
to
On Tue, 13 Jan 2009 09:23:47 -0800 (PST), vitro <iam...@gmail.com> wrote:

>Thank you for all of your replies.
>Jame's first code and that with "calling sub" work on my 64 bit
>gfortran under x64. That with @4 does not. T

The @4 suffix is for 32-bit Windows only. That is a convention for the 32-bit
STDCALL calling convention, intended to help prevent stack corruption by
calling with the wrong number of arguments, since in STDCALL, the called
routine pops the stack. 64-bit Windows (x64 and IA-64) has only one calling
convention, the C convention.
--


Steve Lionel
Developer Products Division

e p chandler

unread,
Jan 13, 2009, 1:56:13 PM1/13/09
to
On Jan 13, 12:02 pm, "James Van Buskirk" <not_va...@comcast.net>
wrote:
> "e p chandler" <e...@juno.com> wrote in messagenews:ecd66d7a-4e64-4bfa...@a29g2000pra.googlegroups.com...
Yes adding -mrtd allows the program to run properly. Just for grins, I
added a delay subroutine

....
call delay


end do
end subroutine sub

subroutine delay
integer i,j,k
do i=1,200
do j=1,1000000
k=i+j
end do
end do
end subroutine delay

Running with -mrtd, there are 20 distinct beeps. Running without -
mrtd, there is an un-ending stream of beeps. Verily the stack has been
well smashed.

My problem with -mrtd is that it has two consequences for a subprogram
in which it is used.

1. routines called by that subprogram
2. how the subprogram itself is called.

On Win32 these may in fact be good. The circumstances in which I use -
mrtd is to compile fortran routines into a DLL so that they can be
called by Visual Basic (or VBA or Excel...). The routines exported
from that DLL need STDCALL calling convention (name mangling is a
separate issue). The routines which MY routine calls, if indeed it
calls any are also STDCALL (name mangling is a separate issue).

Obviously there is no standard way of doing this! Perhaps it might
make sense to have a

use WIN32_API_BINDING

?

I don't have any particular problem with !$DEC ATTRIBUTES except
(Open) Watcom has its own pragma aux, Lahey has its own, Salford has
its own, etc..

At least that might let me CALL a STDCALL routine without making MY
routine STDCALL. Or it might let me make my routine STDCALL without
making routines it calls STDCALL as well.

Again this is outside the realm of Fortran standards. Unless the
standards makers wish to specify some uniform method of inter-
language / inter-system binding not related to C.

Just my 2cents.

-- e

-- e

James Van Buskirk

unread,
Jan 13, 2009, 10:37:25 PM1/13/09
to
"e p chandler" <ep...@juno.com> wrote in message
news:2daf02a9-cec7-4c02...@k1g2000prb.googlegroups.com...

On Jan 13, 12:02 pm, "James Van Buskirk" <not_va...@comcast.net>
wrote:

> Yes adding -mrtd allows the program to run properly.

I tried a modification to get something that might work both in
64-bit gfortran and 32-bit g95:

C:\gfortran\clf\beep>type beep3.f90


module winapi
use ISO_C_BINDING
implicit none
private
integer, parameter, public :: MB_OK = int(Z'00000000', C_LONG)
public MessageBeep
interface

function MessageBeep(uType) bind(C,name=trim(merge( &
'MessageBeep@4', &
'MessageBeep ', &
bit_size(0_C_INTPTR_T) == 32)))


use ISO_C_BINDING
implicit none
integer(C_INT), value :: uType
integer(C_INT) MessageBeep
end function MessageBeep
end interface
end module winapi

program beep3


implicit none
external sub
integer n

n = 20
write(*,*) 'Calling sub'
call sub(n)
write(*,*) 'Returning from sub'

end program beep3

subroutine sub(n)
use winapi
use ISO_C_BINDING, only: C_INT
implicit none
integer(C_INT) result
integer n
integer i

do i = 1, n
result = MessageBeep(MB_OK)

end do
end subroutine sub

C:\gfortran\clf\beep>gfortran -std=f2003 beep3.f90 -obeep3
beep3.f90:8.46:

function MessageBeep(uType) bind(C,name=trim(merge( &
1
Error: Syntax error in NAME= specifier for binding label at (1)

[Also compound errors]

C:\gfortran\clf\beep>gfortran -v
Built by Equation Solution (http://www.Equation.com).
Using built-in specs.
Target: x86_64-pc-mingw32
Configured with:
../gcc-4.4-20081212-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.4-20081212 --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.4-20081212 --with-gcc --with-gnu-ld --with-gnu-as
--
disable-shared --disable-nls --disable-tls --enable-libgomp --enable-languages=c
,fortran --enable-threads=win32 --disable-win32-registry
Thread model: win32
gcc version 4.4.0 20081212 (experimental) (GCC)

Should work as I see it, just doesn't in gfortran.

> My problem with -mrtd is that it has two consequences for a subprogram
> in which it is used.

> 1. routines called by that subprogram
> 2. how the subprogram itself is called.

> On Win32 these may in fact be good. The circumstances in which I use -
> mrtd is to compile fortran routines into a DLL so that they can be
> called by Visual Basic (or VBA or Excel...). The routines exported
> from that DLL need STDCALL calling convention (name mangling is a
> separate issue). The routines which MY routine calls, if indeed it
> calls any are also STDCALL (name mangling is a separate issue).

> Obviously there is no standard way of doing this! Perhaps it might
> make sense to have a

> use WIN32_API_BINDING

> ?

> I don't have any particular problem with !$DEC ATTRIBUTES except
> (Open) Watcom has its own pragma aux, Lahey has its own, Salford has
> its own, etc..

> At least that might let me CALL a STDCALL routine without making MY
> routine STDCALL. Or it might let me make my routine STDCALL without
> making routines it calls STDCALL as well.

> Again this is outside the realm of Fortran standards. Unless the
> standards makers wish to specify some uniform method of inter-
> language / inter-system binding not related to C.

I believe that the f03 standard permits this without inline
defacement of the Fortran source code, but I have yet to sway
any vendor on this issue.

James Van Buskirk

unread,
Jan 14, 2009, 1:18:33 AM1/14/09
to
"Steve Lionel" <Steve....@intel.invalid> wrote in message
news:nbcpm4lu0leorobbm...@4ax.com...

> I had missed the x64 in the subject line, but the OP's wanting CVF as well
> meant that IA-32 issues were still valid.

> I would not expect adding @4 to work in the NAME= specifier. This is to
> give
> the name as it would be written in C, not the fully decorated name (which
> also
> has a leading underscore). The compiler is expected to add any decoration
> that the "companion C processor" would. Even if you succeeded here, you
> also
> need to get the compiler to use STDCALL semantics so that the stack
> doesn't
> get popped twice.

> Given that the default behavior (in absence of /Gm, etc.) of C compilers
> on
> IA-32 Windows is to use the C mechanism, there is no standard-conforming
> way
> to specify STDCALL and you'll need to resort to extensions.

Well, I think it's not so hopeless. If you compile a Fortran source
code file with the switch that causes the companion C compiler to use
the STDCALL convention, you might expect that the result would use
the STDCALL convention as well. This sort of works with gfortran,
with two big problems:

1) gfortran doesn't do the name-mangling and won't even permit it by hand.

2) What if you have to interface to some code such as WIN32 API code that
requires STDCALL and another *.dll that doesn't? What I think compilers
should do is to use the module mechanism to pass along the info as to
what calling convention a procedure abides by. I think that is already
possible in ifort (correct me if I'm wrong) but it doesn't work in
current gfortran. Here is a fantasy example:

C:\gfortran\clf\beep>type gamma.f90
function gamma(Delta_size, L2MAX, A_size, q)
implicit none
integer, parameter :: ep = selected_real_kind(18,4931)
integer i
real(ep) L2
integer Delta_size
real(ep) Delta(Delta_size)
integer L2MAX
integer j
integer A_size
real(ep) A(A_size+1-iand(A_size,1))
real(ep) f
real(ep) gamma
integer q
real(ep) L2diff
real(ep) cleanup

L2 = 0
do i = 1, size(Delta)
Delta(i) = 1.0_ep/(L2MAX+i)
do j = i-1, 1, -1
Delta(j) = Delta(j+1)-Delta(j)
end do
L2 = L2-(-1)**i*Delta(1)/2.0_ep**i
end do
L2 = (-1)**L2MAX*L2
do i = 1, L2MAX
L2 = L2-real((-1)**i,ep)/i
end do

A(1) = 1.0_ep/12
do i = 2, size(A)
A(i) = 0
do j = 1, i/2-1
A(i) = A(i)+A(j)*A(i-j)
end do
if(mod(i,2) == 0) then
A(i) = -(2*A(i)+A(i/2)**2)/(2*i+1)
else
A(i) = -2*A(i)/(2*i+1)
end if
end do
f = 1
do i = 1, size(A)
A(i) = f*A(i)
f = f*(2*i)*(2*i+1)
end do

gamma = 1
do i = 1, q
L2diff = 0
do j = 2**(i-1)+1, 2**i
L2diff = L2diff+1.0_ep/j
end do
L2diff = L2diff-L2
gamma = gamma+L2diff
end do

cleanup = -1/2.0_ep**(q+1)
do i = 1, size(A)
cleanup = cleanup+A(i)/2.0_ep**(2*i*q)
end do

gamma = gamma+cleanup
end function gamma

C:\gfortran\clf\beep>gfortran -Wall -shared gamma.f90 -ogamma.dll
gamma.f90:1:

function gamma(Delta_size, L2MAX, A_size, q)
1
Warning: 'gamma' declared at (1) is also the name of an intrinsic. It can
only
be called via an explicit interface or if declared EXTERNAL.

C:\gfortran\clf\beep>type gamma_mod.f90
module gamma_mod
implicit none
interface
function gamma(Delta_size, L2MAX, A_size, q)
implicit none
integer, parameter :: ep = selected_real_kind(18,4931)
integer Delta_size
integer L2MAX
integer A_size
real(ep) gamma
integer q
end function gamma
end interface
end module gamma_mod

C:\gfortran\clf\beep>gfortran -Wall -c gamma_mod.f90
gamma_mod.f90:4.6:

function gamma(Delta_size, L2MAX, A_size, q)
1
Warning: 'gamma' declared at (1) may shadow the intrinsic of the same name.
In
order to call the intrinsic, explicit INTRINSIC declarations may be
required.

C:\gfortran\clf\beep>type iface.f90
module iface


use ISO_C_BINDING
implicit none
private

integer, parameter, public :: MB_OK = int(Z'00000000', C_LONG)
public MessageBeep

interface
function MessageBeep(uType) bind(C,name='MessageBeep')
use ISO_C_BINDING
implicit none
integer(C_INT), value :: uType
integer(C_INT) MessageBeep
end function MessageBeep
end interface

end module iface

C:\gfortran\clf\beep>gfortran -Wall -c -mrtd iface.f90
f951.exe: warning: -mrtd is ignored in 64bit mode

C:\gfortran\clf\beep>type multi.f90
program multi
use gamma_mod
implicit none
external sub
write(*,*) gamma(24,82,14,7)
write(*,*) 'Calling sub'
call sub(20)
write(*,*) 'Returned from sub'
end program multi

subroutine sub(n)
use iface


use ISO_C_BINDING, only: C_INT
implicit none

integer n
integer i
integer(C_INT) result

do i = 1, n
result = MessageBeep(MB_OK)
end do
end subroutine sub

C:\gfortran\clf\beep>gfortran -Wall multi.f90 gamma.dll -omulti

C:\gfortran\clf\beep>multi
0.57721566490153240000
Calling sub
Returned from sub

Of course it works in 64-bit gfortran because there is only one
calling convention. The lessening of register pressure in that
ISA means that there is not the same impetus to create new and
confusing calling conventions. Well, the arithmetic results
don't look so good... I'll have to leave it to another occasion
to check them.

I don't think it's unreasonable to ask for this example to work
in 32-bit gfortran, except for the fact that scarce resources
may be better spent on more important issues.

Steve Lionel

unread,
Jan 14, 2009, 4:00:18 PM1/14/09
to
On Tue, 13 Jan 2009 23:18:33 -0700, "James Van Buskirk"
<not_...@comcast.net> wrote:

>What I think compilers
>should do is to use the module mechanism to pass along the info as to
>what calling convention a procedure abides by. I think that is already
>possible in ifort (correct me if I'm wrong)

No correction needed. In ifort, all of the calling convention attributes you
specify in an interface are inherited through the module. However, things you
DON'T specify will be interpreted according to the options used to compile the
application that USEs the module. We created the DEFAULT attribute to say
"lock all the calling attributes when the module is compiled". In my perfect
world, this would have been the default fron the start, but by the time we
realized it was an issue we didn't want to break existing applications.

0 new messages