Up until 2014 version of IVF compilers, if MINLOC or MAXLOC had a MASK argument conformable with the array being searched for the minimum or maximum value, the result would be a 0 if no element of the array satisfied the condition in the corresponding element of MASK. I haven't checked since 2014, but in trying to determine why a code that has previously worked is giving absurd results, I narrowed it down to the fact the result of such an inquiry is now 1 (one) instead of 0 (zero). I checked the latest manual for 18.104.22.168 and there is a mention of this in green font (don't know the significance).
My comments/questions are:
1. This is very inconvenient since now one has to test whether MASK has any true entries before using MASK in MINLOC/MAXLOC.
2. A return value of 1 cannot be logically tested since the first element of the array could actually have the minimum or maximum value.
3. Where within the various release notes can one find such changes in compiler behavior documented for easy reference?
4. What is the setting in Microsoft Visual Studio that will allow default to the old behavior?
program main implicit none integer(kind = 4) :: n integer(kind = 4) :: indx(4) real(kind = 4) :: x(4) ! n = 4 x = [-3.0, 2.0, 4.0, -10.0] ! indx = [-1,0,1,1] print *, 'Case 1 (some true elements in mask): ', minval(minloc(x, indx == 1)) ! indx = [-1,0,-1,0] print *, 'Case 2 (all elements of mask are false): ', minval(minloc(x, indx == 1)) ! read * end program main
Case 1 (some true elements in mask): 4 Case 2 (all elements of mask are false): 1
I think intel was previously not standard conformining and thus the change was a correction. The compile option assume old_maxminloc should give the old behaviour. You could test any(indx == 1) first to avoid using special compilers options .
From IVF 17.0 document:
If array has size zero, or every element of mask has the value .FALSE., the value of the result is controlled by compiler option assume [no]old_maxminloc, which can set the value of the result to either 1 or 0.
MAXLOC and MINLOC return 1 when given an empty array as an argument or every element of the mask is false.
IOW use the -noold_maxminloc option to return 0.
BTW this is an example of an option switch that is not instructive as to what/how to use it. (same with the ifort /? information)
A couple of additional comments:
1. When returning a value of 1, the function actually returns a wrong result that results in a serious logic error. If it is all the same to the compiler, why not return a value out of bounds i.e. zero that makes the use of this function much easier?
2. According to Metcalf and Reid Fortran 2008, the Fortran 2003 standard says that zero should be returned, which is where the idea of my implementation originated.
The original implementation in DEC Fortran (and later Intel) returned 1 for such cases. The standard does indeed say that the result should be zero. The default is still the old, nonstandard behavior for performance reasons, You can select the standard behavior with /assume noold_maxminloc or /standard-semantics. There is no Visual Studio option for the former (you can add it under Command Line), but the latter is Fortran > Language > Enable F2003 Semantics > Yes.