PROGRAM MAIN
INTERFACE COS
REAL FUNCTION MYCOS(X)
END FUNCTION
END INTERFACE
CALL SUBR
CONTAINS
SUBROUTINE SUBR
INTRINSIC COS
PRINT *, COS(0.0)
END SUBROUTINE
END
REAL FUNCTION MYCOS(X)
MYCOS = 2.0
END
should print
1.0
or something else like it. The third item in the lists in the cited
sections of
the cited standards says that the call of the generic function COS in
the
PRINT statement should call the intrinsic specific function COS, not
the
external procedure MYCOS. I am sorry to have to admit that Sun
Fortran
gets it wrong. I would like to know if other compilers get it right.
Bob Corbett
I tried this with gfortran (version 4.2.0 under Cygwin), g95 (version
4.0.3, under MinGW) and CVF (version 6.6C, under Windows XP):
gfortran and g95 gave as the answer 1.0, CVF however gave the answer
2.0.
Regards,
Arjen
Wot now ? g95 -v
Using built-in specs.
Target:
Configured with: ../configure --enable-languages=c
Thread model: posix
gcc version 4.0.3 (g95 0.90!) Jul 27 2006
Wot now ?
g95 -Wall -Wextra -fbounds-check -std=f95 -finteger=999999 -flogical=none -freal=NAN -fpointer=none -ftrace=full -g
inter.f90
In file inter.f90:3
REAL FUNCTION MYCOS(X)
1
Warning (163): Actual argument 'x' at (1) does not have an INTENT
In file inter.f90:14
REAL FUNCTION MYCOS(X)
1
Warning (163): Actual argument 'x' at (1) does not have an INTENT
Wot now ? ./a.out
1.
Intel:
Wot now ? /opt/intel/fc/10.0.025/bin/ifort -v
Version 10.0
Wot now ? /opt/intel/fc/10.0.025/bin/ifort inter.f90
Wot now ? ./a.out
2.000000
IBM version 10 ( on Power 5 )
Wot now ? xlf90 -qversion
IBM XL Fortran Enterprise Edition V10.1 for AIX
Version: 10.01.0000.0007
Wot now ? xlf90 -qlanglvl=95pure inter.f90
** main === End of Compilation 1 ===
** mycos === End of Compilation 2 ===
1501-510 Compilation successful for file inter.f90.
Wot now ? ./a.out
1.000000000
Portland Group on Cray XT4
ijb@nid15879:~> ftn -V
/opt/xt-pe/2.0.40/bin/snos64/ftn: INFO: linux target is being used
pgf90 7.0-4 64-bit target on x86-64 Linux
Copyright 1989-2000, The Portland Group, Inc. All Rights Reserved.
Copyright 2000-2007, STMicroelectronics, Inc. All Rights Reserved.
/opt/pgi/7.0.4/linux86-64/7.0-4/lib/f90main.o(.text+0x3c): In function
`main':
: undefined reference to `MAIN_'
ijb@nid15879:~> ftn inter.f90
/opt/xt-pe/2.0.40/bin/snos64/ftn: INFO: linux target is being used
inter.f90:
PGF90-S-0126-Name cos is not an intrinsic function (inter.f90: 9)
ijb@nid15879:~>
(LOL!)
Pathscale on Cray XT4
ijb@nid15876:~> ftn -version
/opt/xt-pe/2.0.40/bin/snos64/ftn: INFO: linux target is being used
Copyright 2000, 2001 Silicon Graphics, Inc. All Rights Reserved.
Copyright 2002, 2003, 2004, 2005, 2006 PathScale, Inc. All Rights Reserved.
See complete copyright, patent and legal notices in the
/opt/pathscale/share/doc/pathscale-compilers-3.0/LEGAL.pdf file.
ijb@nid15876:~> ftn inter.f90
/opt/xt-pe/2.0.40/bin/snos64/ftn: INFO: linux target is being used
ijb@nid15876:~> ./a.out
2.
Hope this fairly sorry story helps,
Ian
> Hope this fairly sorry story helps,
>
> Ian
Yes, it does. Thank you.
I thought of the program as an example that compilers are
likely to get wrong while working on a request for
interpretation for a related matter. The RFI is likely
to be controversial. The program I gave should not be.
Bob Corbett
$ ifort --version
ifort (IFORT) 10.1 20070913
Copyright (C) 1985-2007 Intel Corporation. All rights reserved.
gives 2.0 (wrong?)
$ gfortran --version
GNU Fortran (GCC) 4.1.2 20070925 (Red Hat 4.1.2-27)
Copyright (C) 2007 Free Software Foundation, Inc.
gives 1.0 (right?)
$ pgf90 -V
pgf90 6.0-5 32-bit target on x86 Linux
Copyright 1989-2000, The Portland Group, Inc. All Rights Reserved.
Copyright 2000-2005, STMicroelectronics, Inc. All Rights Reserved.
won't compile it:
$ pgf95 -o test /tmp/test.f90
PGF90-S-0126-Name cos is not an intrinsic function (/tmp/test.f90: 9)
Chip
--
Charles M. "Chip" Coldwell
"Turn on, log in, tune out"
GPG Key ID: 852E052F
GPG Key Fingerprint: 77E5 2B51 4907 F08A 7E92 DE80 AFA9 9A8F 852E 052F
-|robert....@sun.com writes:
-|
-|> According to my understanding of Section 14.1.2.4.1 of the Fortran 95
-|> standard and Section 12.4.4.1 of the Fortran 2003 standard, the
-|> program
-|>
-|> PROGRAM MAIN
-|> INTERFACE COS
-|> REAL FUNCTION MYCOS(X)
-|> END FUNCTION
-|> END INTERFACE
-|> CALL SUBR
-|> CONTAINS
-|> SUBROUTINE SUBR
-|> INTRINSIC COS
-|> PRINT *, COS(0.0)
-|> END SUBROUTINE
-|> END
-|>
-|> REAL FUNCTION MYCOS(X)
-|> MYCOS = 2.0
-|> END
-|>
-|> should print
-|>
-|> 1.0
-|>
-|> or something else like it. The third item in the lists in the cited
-|> sections of
-|> the cited standards says that the call of the generic function COS in
-|> the
-|> PRINT statement should call the intrinsic specific function COS, not
-|> the
-|> external procedure MYCOS. I am sorry to have to admit that Sun
-|> Fortran
-|> gets it wrong. I would like to know if other compilers get it right.
-|
-|$ ifort --version
-|ifort (IFORT) 10.1 20070913
-|Copyright (C) 1985-2007 Intel Corporation. All rights reserved.
-|
-|gives 2.0 (wrong?)
Try using ifort options: -O0 -fltconsistency
Skip Knoble
-|
-|$ gfortran --version
-|GNU Fortran (GCC) 4.1.2 20070925 (Red Hat 4.1.2-27)
-|Copyright (C) 2007 Free Software Foundation, Inc.
-|
-|gives 1.0 (right?)
-|
-|$ pgf90 -V
-|
-|pgf90 6.0-5 32-bit target on x86 Linux
-|Copyright 1989-2000, The Portland Group, Inc. All Rights Reserved.
-|Copyright 2000-2005, STMicroelectronics, Inc. All Rights Reserved.
-|
-|won't compile it:
-|
-|$ pgf95 -o test /tmp/test.f90
-|PGF90-S-0126-Name cos is not an intrinsic function (/tmp/test.f90: 9)
-|
-|Chip
Your team should have a compiler gauntlet? (We find ours extremely
valuable for finding compiler bugs and for detecting questionable code.)
gcc version 4.0.3 (g95 0.90!) Mar 7 2008
$ g95 corbett.f90 && ./a.out
1.
gcc version 4.1.1 20070105 (Red Hat 4.1.1-52)
% gfortran corbett.f90 && ./a.out
1.000000
ifort (IFORT) 10.1 20071116
% ifort corbett.f90 && ./a.out
2.000000
f95: Sun Fortran 95 8.3 Linux_i386 Patch 127145-01 2007/07/31
% f95 corbett.f90 && ./a.out
2.0
gcc version 4.0.1 (g95!) Jan 12 2006
% g95 corbett.f90 && ./a.out
1.
Lahey/Fujitsu Fortran 95 Express Release L6.20d
% lf95 corbett.f90 && ./a.out
Encountered 0 errors, 0 warnings in file corbett.f90.
1.00000000
Compaq Fortran Compiler V1.2.0-1882-48BBF
a2n9% fort corbett.f90 && ./a.out
2.000000
pgf90 6.1-2 32-bit target on x86 Linux
% pgf95 corbett.f90 && ./a.out
PGF90-S-0126-Name cos is not an intrinsic function (corbett.f90: 9)
PathScale EKOPath(TM) Compiler Suite: Version 2.5
% pathf90 corbett.f90 && ./a.out
2.
NAGWare Fortran 95 compiler Release 5.0(347)
% f95 corbett.f90 && ./a.out
Warning: corbett.f90, line 16: Unused dummy argument X
detected at END@<end-of-statement>
[f95 continuing despite warning messages]
1.0000000
Lahey/Fujitsu Linux64 Fortran Express Release L8.00a
% lf95 corbett.f90 && ./a.out
Encountered 0 errors, 0 warnings in file corbett.f90.
1.00000000
pgf95 7.1-5 64-bit target on x86-64 Linux -tp k8-64e
% pgf95 corbett.f90 && ./a.out
PGF90-S-0126-Name cos is not an intrinsic function (corbett.f90: 9)
NAGWare Fortran 95 compiler Release 5.1(347,355,357-364,365)
% f95 corbett.f90 && ./a.out
Warning: corbett.f90, line 16: Unused dummy argument X
detected at END@<end-of-statement>
[f95 continuing despite warning messages]
1.0000000
Absoft 64-bit Fortran 95 10.1.2
% af95 corbett.f90 && ./a.out
2.00000
Intel(R) Fortran Compiler for 32-bit applications, Version 9.1 Build 20070109Z (9.1.041)
% ifort corbett.f90 && ./a.out
2.000000
Regards,
--
Bil Kleb
http://fun3d.larc.nasa.gov
-|-|$ ifort --version
-|-|ifort (IFORT) 10.1 20070913
-|-|Copyright (C) 1985-2007 Intel Corporation. All rights reserved.
-|-|
-|-|gives 2.0 (wrong?)
-|Try using ifort options: -O0 -fltconsistency
-|
-|Skip Knoble
Sorry. The options I previously suggested have
no effect on the results.
Skip
>According to my understanding of Section 14.1.2.4.1 of the Fortran 95
>standard and Section 12.4.4.1 of the Fortran 2003 standard, the
>program
>
>or something else like it. The third item in the lists in the cited
>sections of
>the cited standards says that the call of the generic function COS in
>the
>PRINT statement should call the intrinsic specific function COS, not
>the
>external procedure MYCOS.
Bob,
My reading is somewhat different from yours. The actual wording of the
section you cite is this:
19 (3) If (1) and (2) do not apply, if the scoping unit contains either an
INTRINSIC attribute
20 specification for that name or a USE statement that makes that name
accessible from a
21 module in which the corresponding name is specified to have the INTRINSIC
attribute, and
22 if the reference is consistent with the interface of that intrinsic
procedure, the reference is
23 to that intrinsic procedure.
Note the initial clause "If (1) and (2) do not apply". (1) is:
8 (1) If the reference is consistent with a nonelemental reference to one of
the specific interfaces of
9 a generic interface that has that name and either is in the scoping unit in
which the reference
10 appears or is made accessible by a USE statement in the scoping unit, the
reference is to
11 the specific procedure in the interface block that provides that interface.
The rules in 16.2.3
12 ensure that there can be at most one such specific procedure.
In your program, the reference COS(0.0) *is* consistent with a nonelemental
reference to one of the specific interfaces of the visible generic COS,
therefore (3) does not apply and it would be correct to call MYCOS.
I also found this:
2 C547 (R503) (R1216) If the name of a generic intrinsic procedure is
explicitly declared to have the
3 INTRINSIC attribute, and it is also the generic name in one or more generic
interfaces (12.3.2.1)
4 accessible in the same scoping unit, the procedures in the interfaces and
the specific intrinsic
5 procedures shall all be functions or all be subroutines, and the
characteristics of the specific
6 intrinsic procedures and the procedures in the interfaces shall differ as
specified in 16.2.3.
My head was spinning when I read this, but I interpret it as saying that your
program is non-standard because it explicitly declares COS as INTRINSIC in a
scope where a generic interface containing a procedure that has the same
signature as the intrinsic COS.
If this reading is correct, the proper behavior would be to issue a standards
violation diagnostic for the INTRINSIC COS, but otherwise calling MYCOS (and
printing 2.0) is right.
I am not as steeped in the standard as some so I welcome counterarguments.
--
Steve Lionel
Developer Products Division
Intel Corporation
Nashua, NH
For email address, replace "invalid" with "com"
User communities for Intel Software Development Products
http://softwareforums.intel.com/
Intel Fortran Support
http://support.intel.com/support/performancetools/fortran
My Fortran blog
http://www.intel.com/software/drfortran
F2003 16.2.3 refers one to C.11.2, which reduces the head-spinning
rate and would seem to support Steve's interpretation, but of course
it's a nonnormative note.
-- John Harper, School of Mathematics, Statistics and Computer Science,
Victoria University, PO Box 600, Wellington 6140, New Zealand
e-mail john....@vuw.ac.nz phone (+64)(4)463 6780 fax (+64)(4)463 5045
<robert....@sun.com> wrote in message
news:2d04c3b1-b87c-4c28...@s33g2000pri.googlegroups.com...
>I would like to know if other compilers get it right.
>
> Bob Corbett
I had results similar to Bill Kleb's downthread, who truly puts it through
the gauntlet. Currently, my 2 means of testing are gfortran 4.3.0 and Plato
3 from silverfrost, which does well wtih f95, although gives 2.0 here as did
other windows-friendly f95 implementations.
I would like to get fortran 2003 (and c99) in the crosshairs by having a sun
partition. Back when I had broadband, I downloaded a zip file for this
whose ensuing executable failed its own checksum test and was thereafter
importuned by real life. Can someone get a sun disc, and therewith another
f03 capability, for anywhere near ten bucks?
--
"That this social order with its pauperism, famines, prisons, gallows,
armies, and wars is necessary to society; that still greater disaster
would ensue if this organization were destroyed; all this is said only
by those who profit by this organization, while those who suffer from it
- and they are ten times as numerous - think and say quite the contrary."
~~ Leo Tolstoy
> My head was spinning when I read this, but I interpret it as saying that
> your
> program is non-standard because it explicitly declares COS as INTRINSIC in
> a
> scope where a generic interface containing a procedure that has the same
> signature as the intrinsic COS.
> If this reading is correct, the proper behavior would be to issue a
> standards
> violation diagnostic for the INTRINSIC COS, but otherwise calling MYCOS
> (and
> printing 2.0) is right.
> I am not as steeped in the standard as some so I welcome counterarguments.
C:\gfortran\clf\cos_test>type cos_test.f90
PROGRAM MAIN
INTERFACE COS
REAL FUNCTION MYCOS(X)
END FUNCTION
END INTERFACE
CALL SUBR
CONTAINS
SUBROUTINE SUBR
INTRINSIC COS
PRINT *, COS(0.0)
PRINT *, COS([0.0])
PRINT *, FUN(COS, 0.0)
END SUBROUTINE
REAL FUNCTION FUN(F,X)
REAL F
EXTERNAL F
REAL X
FUN = F(X)
END FUNCTION
END
REAL FUNCTION MYCOS(X)
MYCOS = 2.0
END
C:\gfortran\clf\cos_test>ifort /stand:f03 cos_test.f90
Intel(R) Fortran Compiler for Intel(R) EM64T-based applications, Version 9.1
Build 20061104
Copyright (C) 1985-2006 Intel Corporation. All rights reserved.
Microsoft (R) Incremental Linker Version 8.00.40310.39
Copyright (C) Microsoft Corporation. All rights reserved.
-out:cos_test.exe
-subsystem:console
cos_test.obj
C:\gfortran\clf\cos_test>cos_test
2.000000
1.000000
1.000000
C:\gfortran\clf\cos_test>C:\gcc_equation\bin\x86_64-pc-mingw32-gfortran -std=f20
03 cos_test.f90 -ocos_test
C:\gfortran\clf\cos_test>cos_test
1.00000000
1.00000000
1.00000000
I think ifort is correct here and that the program conforms. In
resolution of generic procedures, a specific procedure with the
correct rank trumps an elemental specific procedure, so the first line
of output should be 2.0. A specific procedure with a scalar dummy
can't match a reference with an array actual argument, so the
second line should be 1.0. Finally, we needed the INTRINSIC
statement so that we could pass COS as an actual argument with
the result that line 3 prints out 1.0.
--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end
>I think ifort is correct here and that the program conforms. In
>resolution of generic procedures, a specific procedure with the
>correct rank trumps an elemental specific procedure, so the first line
>of output should be 2.0. A specific procedure with a scalar dummy
>can't match a reference with an array actual argument, so the
>second line should be 1.0. Finally, we needed the INTRINSIC
>statement so that we could pass COS as an actual argument with
>the result that line 3 prints out 1.0.
I don't like this. This would mean that the local name COS has two different
meanings in the same program unit. The language tries hard to make sure that
never happens.
I'll venture here that this program is non-conforming for the same reason I
cited earlier. What's worse is that I can't think of how one would pass the
intrinsic COS if that's really what you wanted. You need to pass a specific,
not a generic, but the specific name is also COS in this case!
> I don't like this. This would mean that the local name COS has two
> different
> meanings in the same program unit. The language tries hard to make sure
> that
> never happens.
I'm not sure that I catch the meaning of this paragraph. After all, it's
commonplace to have a fixed-rank specific procedure that has the same
generic name as the corresponding elemental procedure. That feature is
there because it may be desirable to write out a highly-optimized
procedure for a given rank, but also to hedge ones bets by providing an
elemental procedure that would otherwise cover the optimize case. In
reading 12.4.4.1 of N1601.pdf:
"(1) If the reference is consistent with a nonelemental reference to one
of the specific interfaces of a generic interface that has that name and
either is in the scoping unit in which the reference appears or is made
accessible by a USE statement in the scoping unit, the reference is to
the specific procedtre in the interface block that provides that
interface. The rules in 16.2.3 ensure that there can be at most one
such specific procedure.
(2) If (1) does not apply, if the reference is consistent with an
elemental reference to one of the specific interfaces of a generic
interface that has that name and either is in the scoping unit in which
the reference appears or is made accessible by a USE statement in the
scoping unit, the reference is to the specific elemental procedure in
the interface block that provides that interface. The rules in 16.2.3
ensure that there can be at most one such specific elemental procedure."
This is saying that nonelemental procedures trump elemental ones. The
compiler is supposed to compare all the nonelemental procedures first
and use one of those if it matches, and only if no nonelemental
procedure works, then shuffle through the list of elemental procedures
to see if one of them works. If elemental procedures conflicted with
elemental procedures in the fashion suggested, why would there be a
need to separate parts (1) and (2) above instead of just making them
into one big part (1) where no distinction was made between elemental
and nonelemental procedures?
Here is an example:
C:\gfortran\clf\cos_test>type ex1.f90
module cos_mod
implicit none
interface enisoc
module procedure element, enisoc
end interface enisoc
contains
pure function enisoc(x)
real, intent(in) :: x
real enisoc
enisoc = 2
end function enisoc
elemental function element(x)
real, intent(in) :: x
real element
element = cos(x)
end function element
end module cos_mod
program main
use cos_mod
implicit none
real fun
external fun
print *, enicos(1.0)
print *, enicos([1.0])
print *, fun(enicos, 1.0)
end program main
function fun(f,x)
implicit none
real fun
real f
real x
fun = f(x)
end function fun
C:\gfortran\clf\cos_test>c:\gcc_equation\bin\x86_64-pc-mingw32-gfortran -std=f20
03 ex1.f90 -oex1
ex1.f90:4.38:
module procedure element, enisoc
1
Error: Ambiguous interfaces 'enisoc' and 'element' in generic interface
'enisoc'
at (1)
ex1.f90:23.14:
use cos_mod
1
Fatal Error: Can't open module file 'cos_mod.mod' for reading at (1): No
such fi
le or directory
x86_64-pc-mingw32-gfortran: Internal error: Aborted (program f951)
Please submit a full bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.
C:\gfortran\clf\cos_test>ifort /stand:f03 ex1.f90
Intel(R) Fortran Compiler for Intel(R) EM64T-based applications, Version 9.1
Build 20061104
Copyright (C) 1985-2006 Intel Corporation. All rights reserved.
ex1.f90(7) : Warning: The type/rank/keyword signature for this specific
procedur
e matches another specific procedure that shares the same generic-name.
[ENISO
C]
pure function enisoc(x)
--------------------^
ex1.f90(28) : Error: This name does not have a type, and must have an
explicit t
ype. [ENICOS]
print *, enicos(1.0)
------------^
compilation aborted for ex1.f90 (code 1)
That proves my point, or would if any compiler accepted it :)
> I'll venture here that this program is non-conforming for the same reason
> I
> cited earlier. What's worse is that I can't think of how one would pass
> the
> intrinsic COS if that's really what you wanted. You need to pass a
> specific,
> not a generic, but the specific name is also COS in this case!
Of course you can always access a specific version of an intrinsic.
If it has a specific name (the new versions aren't always so endowed)
you can rename it:
C:\gfortran\clf\cos_test>type ex2.f90
MODULE SPECIFIC
INTRINSIC COS
END MODULE SPECIFIC
MODULE RENAME
USE SPECIFIC, ONLY: ENISOC => COS
END MODULE RENAME
PROGRAM MAIN
INTERFACE COS
REAL FUNCTION MYCOS(X)
END FUNCTION
END INTERFACE
CALL SUBR
CONTAINS
SUBROUTINE SUBR
USE RENAME, ONLY: ENISOC
PRINT *, COS(0.0)
PRINT *, FUN(ENISOC, 0.0)
END SUBROUTINE
REAL FUNCTION FUN(F,X)
REAL F
EXTERNAL F
REAL X
FUN = F(X)
END FUNCTION
END
REAL FUNCTION MYCOS(X)
MYCOS = 2.0
END
C:\gfortran\clf\cos_test>c:\gcc_equation\bin\x86_64-pc-mingw32-gfortran -std=f20
03 ex2.f90 -oex2
C:\gfortran\clf\cos_test>ex2
2.0000000
1.00000000
C:\gfortran\clf\cos_test>ifort /stand:f03 ex2.f90
Intel(R) Fortran Compiler for Intel(R) EM64T-based applications, Version 9.1
Build 20061104
Copyright (C) 1985-2006 Intel Corporation. All rights reserved.
Microsoft (R) Incremental Linker Version 8.00.40310.39
Copyright (C) Microsoft Corporation. All rights reserved.
-out:ex2.exe
-subsystem:console
ex2.obj
C:\gfortran\clf\cos_test>ex2
2.000000
1.000000
And even if it didn't you could always guess its secret C binding
name:
C:\gfortran\clf\cos_test>type ex3.f90
PROGRAM MAIN
INTERFACE COS
REAL FUNCTION MYCOS(X)
END FUNCTION
END INTERFACE
CALL SUBR
CONTAINS
SUBROUTINE SUBR
INTERFACE
REAL(C_FLOAT) FUNCTION ENISOC(X) BIND(C,NAME='cosf')
USE ISO_C_BINDING, ONLY: C_FLOAT
IMPLICIT NONE
REAL(C_FLOAT) X
END FUNCTION ENISOC
END INTERFACE
PRINT *, COS(0.0)
PRINT *, FUN(ENISOC, 0.0)
END SUBROUTINE
REAL FUNCTION FUN(F,X)
REAL F
EXTERNAL F
REAL X
FUN = F(X)
END FUNCTION
END
REAL FUNCTION MYCOS(X)
MYCOS = 2.0
END
C:\gfortran\clf\cos_test>c:\gcc_equation\bin\x86_64-pc-mingw32-gfortran -std=f20
03 ex3.f90 -oex3
C:\gfortran\clf\cos_test>ex3
2.0000000
1.00000000
> Can someone get a sun disc, and therewith another
> f03 capability, for anywhere near ten bucks?
Someone can get Sun Studio 12, which includes Sun Fortran, on
DVD for ten dollars. Go to the URL
http://developers.sun.com/sunstudio/downloads
Click on the media kit. That should load the sun store webpage
for the Sun Studio 12 media kit.
Sun Fortran runs on Solaris for SPARC, AMD, and Intel, and on
Linux for AMD and Intel.
Bob Corbett
Let's look at the language of the standard more closely.
Item (1) of Section 12.4.4.1 of the Fortran 2003 standard
states
(1) If the reference is consistent with a nonelemental
reference to one of the specific interfaces of a
generic interface that has that name and either is
^^
in the scoping unit in which the reference appears
^^ ^^^ ^^^^^^^ ^^^^ ^^ ^^^^^ ^^^ ^^^^^^^^^ ^^^^^^^
or is made accessible by a USE statement in the
scoping unit, the reference is to the specific
procedure in the interface block that provides
that interface. The rules in 16.2.3 ensure that
there can be at most one such specific procedure.
In the program
PROGRAM MAIN
INTERFACE COS
REAL FUNCTION MYCOS(X)
END FUNCTION
END INTERFACE
CALL SUBR
CONTAINS
SUBROUTINE SUBR
INTRINSIC COS
PRINT *, COS(0.0)
END SUBROUTINE
END
REAL FUNCTION MYCOS(X)
MYCOS = 2.0
END
the explicit generic interface for COS is not in the same
scoping unit as the reference, and so item (1) does not
apply.
One might argue that the genric interface is "in the
scoping unit" by host association. By that reasoning, a
generic interface "made accessible by a USE statement in
the scoping unit" would be "in the scoping unit" by virtue
of use association, and so the part of the statement about
USE statements would be pointless. Furthermore, if host
association caused a generic interface to be "in the
scoping unit," the whole of item (4) in Section 12.4.4.1
would never apply to anything.
> I also found this:
>
> 2 C547 (R503) (R1216) If the name of a generic intrinsic procedure is
> explicitly declared to have the
> 3 INTRINSIC attribute, and it is also the generic name in one or more generic
> interfaces (12.3.2.1)
> 4 accessible in the same scoping unit, the procedures in the interfaces and
> the specific intrinsic
> 5 procedures shall all be functions or all be subroutines, and the
> characteristics of the specific
> 6 intrinsic procedures and the procedures in the interfaces shall differ as
> specified in 16.2.3.
>
> My head was spinning when I read this, but I interpret it as saying that your
> program is non-standard because it explicitly declares COS as INTRINSIC in a
> scope where a generic interface containing a procedure that has the same
> signature as the intrinsic COS.
>
> If this reading is correct, the proper behavior would be to issue a standards
> violation diagnostic for the INTRINSIC COS, but otherwise calling MYCOS (and
> printing 2.0) is right.
This observation gets to the controversial issue I mentioned
in my original post. A former committee member has pointed
out that Section 16.2.3 probably doesn't say what it was
intended to mean. The example he gave was along the lines
of
PROGRAM MAIN
INTERFACE F
REAL FUNCTION F(I)
END FUNCTION
END INTERFACE
CALL SUBR
CONTAINS
SUBROUTINE SUBR
REAL F(1)
F = 1.0
PRINT *, F
END SUBROUTINE
END
According to the interpretation of the standard you appear
to be assuming, the program above is not standard
conforming. At least some members of the committee seem
to think it was intended to be conforming.
All of this has been made more important in Fortran 2003
than it was in Fortran 95, because some members of the
committee think that the new requirement added to the
conformance section of tte standard, item (6) of
Section 1.5, is equivalent to a constraint. In the
Fortran 2008 draft, some of the requirements have been
explicitly made constraints. The rationale given for
making them constraints was that they were already
effectively constraints.
Bob Corbett
I have heard that it's bad manners to follow-up to your own post
but I was hoping in vain that someone else would correct my
errors.
> I'm not sure that I catch the meaning of this paragraph. After all, it's
> commonplace to have a fixed-rank specific procedure that has the same
> generic name as the corresponding elemental procedure. That feature is
> there because it may be desirable to write out a highly-optimized
> procedure for a given rank, but also to hedge ones bets by providing an
> elemental procedure that would otherwise cover the optimize case.
I still think it's correct up to here.
> In
> reading 12.4.4.1 of N1601.pdf:
> "(1) If the reference is consistent with a nonelemental reference to one
> of the specific interfaces of a generic interface that has that name and
> either is in the scoping unit in which the reference appears or is made
> accessible by a USE statement in the scoping unit, the reference is to
> the specific procedtre in the interface block that provides that
> interface. The rules in 16.2.3 ensure that there can be at most one
> such specific procedure.
> (2) If (1) does not apply, if the reference is consistent with an
> elemental reference to one of the specific interfaces of a generic
> interface that has that name and either is in the scoping unit in which
> the reference appears or is made accessible by a USE statement in the
> scoping unit, the reference is to the specific elemental procedure in
> the interface block that provides that interface. The rules in 16.2.3
> ensure that there can be at most one such specific elemental procedure."
> This is saying that nonelemental procedures trump elemental ones. The
> compiler is supposed to compare all the nonelemental procedures first
> and use one of those if it matches, and only if no nonelemental
> procedure works, then shuffle through the list of elemental procedures
> to see if one of them works.
I didn't notice in the above that the standard isn't really saying this.
There are two ways this way of thinking conflicts with the standard:
1) The standard says that nonelemental REFERENCES trump elemental
REFERENCES. A reference to an elemental procedure with all scalar
actual arguments is not an elemental reference, see N1601.pdf, section
12.4.2:
"A reference to an elemental function (12.7) is an elemental reference
if one or more actual arguments are arrays and all array arguments
have the same shape."
Similar verbiage exists in section 12.4.3 for subroutines.
2) The standard does not say that elemental references always trump
nonelemental references. Host-associated names go to the back of the
bus in such a way that they can be blocked by other names. Thanks to
Bob Corbett who pointed this out with clarity in
http://groups.google.com/group/comp.lang.fortran/msg/3ca1c4732c6909e6
> If elemental procedures conflicted with
> elemental procedures in the fashion suggested, why would there be a
> need to separate parts (1) and (2) above instead of just making them
> into one big part (1) where no distinction was made between elemental
> and nonelemental procedures?
> Here is an example:
> C:\gfortran\clf\cos_test>ifort /stand:f03 ex1.f90
> pure function enisoc(x)
> --------------------^
> ex1.f90(28) : Error: This name does not have a type, and must have an
> explicit t
> ype. [ENICOS]
> print *, enicos(1.0)
> ------------^
> compilation aborted for ex1.f90 (code 1)
And now in my example I misspelled ENISOC. Just shows how a bad
choice of variable names can make a program unreadable and
untypable. Fixing up my example:
C:\gfortran\clf\cos_test>type ex1a.f90
module cos_mod
implicit none
interface enisoc
module procedure element, enisoc
end interface enisoc
contains
pure function enisoc(x)
real, intent(in) :: x
real enisoc
enisoc = 2
end function enisoc
elemental function element(x)
real, intent(in) :: x
real element
element = cos(x)
end function element
end module cos_mod
program main
use cos_mod
implicit none
real fun
external fun
print *, enisoc(0.0)
print *, enisoc([0.0])
print *, fun(enisoc, 0.0)
end program main
function fun(f,x)
implicit none
real fun
real f
real x
fun = f(x)
end function fun
C:\gfortran\clf\cos_test>c:\gcc_equation\bin\x86_64-pc-mingw32-gfortran -std=f20
03 ex1a.f90 -oex1a
ex1a.f90:4.38:
module procedure element, enisoc
1
Error: Ambiguous interfaces 'enisoc' and 'element' in generic interface
'enisoc'
at (1)
ex1a.f90:23.14:
use cos_mod
1
Fatal Error: Can't open module file 'cos_mod.mod' for reading at (1): No
such fi
le or directory
x86_64-pc-mingw32-gfortran: Internal error: Aborted (program f951)
Please submit a full bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.
C:\gfortran\clf\cos_test>ifort /stand:f03 ex1a.f90
Intel(R) Fortran Compiler for Intel(R) EM64T-based applications, Version 9.1
Build 20061104
Copyright (C) 1985-2006 Intel Corporation. All rights reserved.
ex1a.f90(7) : Warning: The type/rank/keyword signature for this specific
procedu
re matches another specific procedure that shares the same generic-name.
[ENIS
OC]
pure function enisoc(x)
--------------------^
Microsoft (R) Incremental Linker Version 8.00.40310.39
Copyright (C) Microsoft Corporation. All rights reserved.
-out:ex1a.exe
-subsystem:console
ex1a.obj
C:\gfortran\clf\cos_test>ex1a
2.000000
1.000000
2.000000
So gfortran rejects it and ifort accepts it. Which is right?
Well, according to the literal words of the standard I think
they both are. As stated above, although procedures that accept
array arguments can override elemental procedures, procedures
that have only scalar arguments can't because a conflicting
reference to the elemental proceedure would not be an elemental
reference. Quirk of the standard as I see it, but it's what the
standard says. Thus gfortran rejects it and ifort accepts it
with a warning and does perform the override as desired. ifort
should insert the keywords "QUIRK IN STANDARD" in their warning
message, though :)
Now for a fixed-up version of this example that does perform
the override as in Note 12.34:
C:\gfortran\clf\cos_test>type ex1b.f90
module cos_mod
implicit none
interface enisoc
module procedure element, enisoc
end interface enisoc
contains
pure function enisoc(x)
real, intent(in) :: x(:)
real enisoc(size(x))
enisoc = 2
end function enisoc
elemental function element(x)
real, intent(in) :: x
real element
element = cos(x)
end function element
end module cos_mod
program main
use cos_mod
implicit none
! real fun ! gfortran should reject if this line uncommented
interface
function fun(f,x)
implicit none
interface
pure function f(x)
real, intent(in) :: x(:)
real f(size(x))
end function f
end interface
real x(:)
! real fun(size(f(x))) ! ICE with ifort if this line in force
real fun(size(x)) ! ifort handles this OK
end function fun
end interface
print *, enisoc(0.0)
print *, enisoc([0.0])
print *, fun(enisoc, [0.0])
end program main
function fun(f,x)
implicit none
interface
pure function f(x)
real, intent(in) :: x(:)
real f(size(x))
end function f
end interface
real x(:)
real fun(size(f(x)))
fun = f(x)
end function fun
C:\gfortran\clf\cos_test>c:\gcc_equation\bin\x86_64-pc-mingw32-gfortran -std=f20
03 ex1b.f90 -oex1b
C:\gfortran\clf\cos_test>ex1b
1.00000000
2.0000000
2.0000000
C:\gfortran\clf\cos_test>ifort /stand:f03 ex1b.f90
Intel(R) Fortran Compiler for Intel(R) EM64T-based applications, Version 9.1
Build 20061104
Copyright (C) 1985-2006 Intel Corporation. All rights reserved.
Microsoft (R) Incremental Linker Version 8.00.40310.39
Copyright (C) Microsoft Corporation. All rights reserved.
-out:ex1b.exe
-subsystem:console
ex1b.obj
C:\gfortran\clf\cos_test>ex1b
1.000000
2.000000
2.000000
So the example works, and even better it exposes a couple of errors
in gfortran and ifort as noted in the comments.
Now I think I begin to understand what the thread is about: a name
can refer to multiple things, such as a generic name, a specific
procedure name, and an intrinsic procedure name, and the standard
permits names of perhaps unrelated things to block host-associated
names in a perhaps quirky, nonintuitive and surprising fashion.
They make you register, but it's painless, given that you actually want
something to show up in your mailbox. They don't tell you at the end that
your phony-balonay sun identity does not match your credit card.
I think my state gets the fifty cents in tax. I get good software and build
local roads at the same. Win-win.
--
"Shopping for toilets isn't the most fascinating way to spend a Saturday
afternoon. But it beats watching cable news."
~~ Booman
I should have mentioned that the Linux version on the DVD is
packaged as RPMs. The tarball version that is available on
the website is not included on the DVD.
Bob Corbett