- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear all,
I think, the ifort compiler 16.0.0 and also previous ones behave strange, when turning on pointer checking ("-check pointers") and passing an unallocated array as actual argument to an optional array dummy argument in a subroutine. The code below compiles and runs fine without the "-check pointers" option, but triggers a false error during run-time when the option is turned on during the compilation.
Bálint
module testmod implicit none contains subroutine testSub(aa, bb) integer, intent(in) :: aa(:) integer, intent(in), optional :: bb(:) print *, "AA:", aa if (present(bb)) then print *, "BB:", bb else print *, "BB NOT PRESENT" end if end subroutine testSub end module testmod program test use testmod implicit none integer, allocatable :: aa(:), bb(:) allocate(aa(2)) aa(:) = -1 call testSub(aa, bb=bb) allocate(bb(2)) aa(:) = -2 bb(:) = -4 call testSub(aa, bb=bb) end program test
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Your example code touched upon some Fortran language rules that I had to educate myself about. The question I had was "can one distinguish between (i) a non-present optional allocatable argument, and (ii) a present optional unallocated argument?" I had to look up the Fortran Standard, and the following excerpt answers the question. The excerpt also shows (Restriction-3(1)) that your program is in error in that it references (on Line-12) the unallocated dummy argument bb in the first call to the subroutine.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
mecej4 wrote:
Your example code touched upon some Fortran language rules that I had to educate myself about. The question I had was "can one distinguish between (i) a non-present optional allocatable argument, and (ii) a present optional unallocated argument?" I had to look up the Fortran Standard, and the following excerpt answers the question. The excerpt also shows (Restriction-3(1)) that your program is in error in that it references (on Line-12) the unallocated dummy argument bb in the first call to the subroutine ...
I don't think the above is correct. Third bullet under point 1 from section 12.5.1.12 shown above makes it clear, "A dummy argument.. is not present if the dummy argument .. does not have the ALLOCATABLE .. and corresponds to an actual argument that .. has the ALLOCATABLE attribute and is not allocated .." This is indeed the case in the code shown in the original post, so mecej4's assessment "the program is in error" appears to be incorrect.
Note the current Fortran standard i.e, 2008 (my reference basis is WD 1539-1, J3/10-007r1 (F2008 Working Document), 24th November 2010 16:43) also says in the Introduction, "A null pointer or unallocated allocatable can be used to denote an absent nonallocatable nonpointer optional argument."
The issue here is that Intel Fortran does not have this particular Fortran 2008 feature implemented.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The word "present" can be quite confusing here. Most people would see "call sub(...,optarg=arg)" and think that optarg is "present" because it is there, in plain sight. The Fortran standard carves out an exception: optarg is not "present" in the Fortran sense in that call if arg happens to be allocatable and not allocated. In that case, the argument arg is present in the textual sense, but PRESENT(arg) yields the value .FALSE.
A null pointer or unallocated allocatable can be used to denote an absent nonallocatable nonpointer optional argument
Fine, but what does that say about a present, allocatable, but unallocated, optional argument (with "present" used in the sense of common parlance)? It seems to me that the standard is hinting that for such arguments ALLOCATED and PRESENT are equivalent, in which case my statement about referencing bb was wrong. However, it is a bit disquieting that PRESENT has different meanings depending upon the nature of its argument. While writing the subroutine body, I would not be able to tell if PRESENT(arg) is .FALSE. because arg was used in the call but is allocatable and unallocated, or because arg was left out of the argument list in the call.
Am I creating confusion where there was none?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
mecej4 wrote:
.. While writing the subroutine body, I would not be able to tell if PRESENT(arg) is .FALSE. because arg was used in the call but is allocatable and unallocated, or because arg was left out of the argument list in the call.
Am I creating confusion where there was none?
As someone who has to write a few subroutines with OPTIONAL dummy arguments, it has not mattered to me whether the "arg was used in the call but is allocatable and unallocated" or "arg was left out of the argument list in the call." Both these situations are treated similarly to that of an absent dummy argument and that hasn't caused any confusion or issues, as far as I can tell!
Now, interpreting the Fortran standard is indeed highly subjective and one can never be sure if one got it right. However from everything I've seen, the code in the original post is valid with respect to Fortran 2008 and I've come across some discussions with respect to gfortran elsewhere that are consistent with the above code being conformant, and an additional bit of validation is gfortran which does support the particular Fortran 2008 feature runs just fine on the original code:
AA: -1 -1 BB NOT PRESENT AA: -2 -2 BB: -4 -4
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
According to MRCs Modern Fortran, that was the intended behavior. When calling a routine with several optional arguments, you could end up with a cascade of if statements, when several call combinations are possible depending on your program status. (This is exactly the case in the scientific code I am developing). With Fortran 2008, this is greatly simplified, as you just pass allocatable arrays, and those, which do not make sense in the current program status, are not allocated anyway, so passing them would still make the present() function on the dummy argument in the subroutine to deliver .false..
IMHO, the Intel compiler does exactly the right thing, when the '-check pointers' option is not used during compilation and behaves the same way as several other recent Fortran compilers I've tried. It is only disturbing, that you can not use that important checking facility any more, as it gives a false positive alarm during run-time.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page