- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Robert
Code:
PROGRAM ef
IMPLICIT none
REAL :: ar(10)
COMPLEX :: ac(10)
INTEGER :: i
COMPLEX :: sub1 ! the definition of the first function
ar=[(i,i=1,10)] ! initialise
ac=sub1(ar) ! call the first elemental function
write(*,'(2f10.4)') ac(1:10) ! print some results
STOP
END
!
COMPLEX ELEMENTAL FUNCTION sub1(ar) ! the first elem. func
IMPLICIT none
REAL,INTENT(in) :: ar
! explicit interface
INTERFACE
COMPLEX ELEMENTAL FUNCTION sub2(ar)
REAL, INTENT(in) :: ar
END FUNCTION sub2
END INTERFACE
!
sub1=3.*sub2(ar) ! call the second elemental function
RETURN
END
!
COMPLEX ELEMENTAL FUNCTION sub2(ar) ! the second elem. function
IMPLICIT none
REAL,INTENT(in) :: ar
sub2=CMPLX(0.,ar**2)
RETURN
END
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What do you mean when you say "But without this addition it fails"? I don't have any problem compiling your code, with or without /warn:all.
The resulting executable, on the other hand, doesn't output the correct results because you're stating that the first function is:
[fortran]complex function sub1(ar) implicit none real, intent(IN) :: arWhat I mean is that the definition of the first function in the program unit does not imply that the function sub1 is elemental, so sub1 is being called only once ---and the returned scalar is being assigned to the ac array.
... end[/fortran]
The /warn:all flag implies /warn:interfaces which in turn implies /gen-interfaces. So with that option, a temporary module is being generated for every external function, and that's what corrects the mistake you made.
An easily corrected version of your code (with no interface blocks), would be:
[fortran]module subs contains complex elemental function sub1(ar) ! the first elem. func implicit none real,intent(in) :: ar sub1 = 3. * sub2(ar) ! call the second elemental function return end function complex elemental function sub2(ar) ! the second elem. function implicit none real,intent(in) :: ar sub2 = CMPLX(0., ar ** 2) return end function end module program ef use subs implicit none real :: ar(10) complex :: ac(10) integer :: i ar = [(i, i = 1, 10)] ! initialise ac = sub1(ar) ! call the first elemental function write(*,'(2f10.4)') ac ! print some results end program [/fortran]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ELEMENTAL (as well as PURE) attribute requires an explicit interface, which you failed to provide. Without the interface, the compiler does not know that it should vectorize the call to Sub1, and calls it only once.
Now comes the /check:all /warn:all, which automatically generates the explicit interfaces, for the purpose of argument checking. However, the /check:all /warn:all only compares for matching of argument datatypes and shapes, not for other features. It finds the real array actual argument, and real scalar dummy argument, which would be illegal if it weren't for ELEMENTAL. Having find the ELEMENTAL attribute, the checker is happy. Thus, it "fixed" the problem as a side effect.
Thus, it is a minor flaw (or a feature) in /warn:all, but it's quite understandable why Intel folks overlooked it (or do not regard it as a bug).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
However, one of the attributes that make up the quality of a compiler is the usefulness of the error messages that it gives the user when asked to compile non-conforming code. High in quality we know the Intel compiler to be; but, in this particular case, I find it deficient, for the following reasons.
With /warn:all correct results are produced, whereas with /check:all wrong results are produced. In neither case is any message given, either at compile time or during the run.
Intuitively, I expect "warn" to tell me about problems detected at compile-time, and "check" to tell me about problems detected at run-time. It is unsettling for the compiler to correct errors behind the scenes, with some options and only with some types of error, and not give out any error or warning messages. Without error messages, one has to examine the automatically produced interfaces and find the root cause of the error, if one has an inkling that it is the interfaces that hold the clues.
A competing compiler gives the following run-time message with Robert's original code, with checks turned on:
"An attribute of argument 1 is inconsistent (actual argument ar: array name, dummy argument ar: scalar variable name)."
"error occurs at sub1_ line 13 "
Line 13: COMPLEX ELEMENTAL FUNCTION sub1(ar) ! the first elem. func
This message is clear and goes straight to the point.
A third compiler gives a compile time error:
"Error: elemo.f90: Argument AR (no. 1) in reference to SUB1 from EF is not scalar"
This example shows some of the rough edges of /warn:all, which is a recent Intel innovation. We hope Intel will polish these rough edges while preparing forthcoming releases.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
you both convinced me that I did made an error. After incorporating an explicit interface in the calling program,any problem is gone. I presume I have misread par. 6.10 of Metcalf c.s.; in any case in the standard, par. 12.6 "Pure Procedure"C1270 leaves no room for any misinterpretation.
Having said this, the situationleaves me in a somewhat uncomfortable mood. The code that I initially used turned out to be basically wrong. The use of the compuler option /warn:all caused theerror beingmade undetectable. So, anexecutable is generated based on a incorrect code. That soundsvery friendly but is, to my opinion, undesirable, to put it mildly. An error in the code must produce an error somewhere in the codedevelopment proces.Preferably in the compile phase (although Iunderstand that this is impossilbe in this case) or during execution, so during testing the construct. The compiler option /nogen-interfaces thus become now standard to my command line!
Again, thanksfor your nice help!
Robert

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page