|
Prev: Good book on FORTRAN OT
Next: branch prediction?
From: Gerry Ford on 10 Apr 2008 20:15 <robert.corbett(a)sun.com> wrote in message news:2d04c3b1-b87c-4c28-8e55-b51df885774e(a)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
From: James Van Buskirk on 10 Apr 2008 20:28 "Steve Lionel" <Steve.Lionel(a)intel.invalid> wrote in message news:29usv3l33ltn44h1tnfvb7nlttuh1168ci(a)4ax.com... > 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
From: Steve Lionel on 11 Apr 2008 14:52 On Thu, 10 Apr 2008 18:28:08 -0600, "James Van Buskirk" <not_valid(a)comcast.net> wrote: >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! -- 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
From: James Van Buskirk on 11 Apr 2008 16:25 "Steve Lionel" <Steve.Lionel(a)intel.invalid> wrote in message news:77cvv31v60kpdslb59rhq246d7k8g8sqmd(a)4ax.com... > 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 -- write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, & 6.0134700243160014d-154/),(/'x'/)); end
From: robert.corbett on 11 Apr 2008 22:47
On Apr 10, 1:42 pm, Steve Lionel <Steve.Lio...(a)intel.invalid> wrote: > On Thu, 10 Apr 2008 01:21:52 -0700 (PDT), robert.corb...(a)sun.com wrote: > 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. 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 |