On 12/19/21 5:37 AM, Daniel Feenberg wrote:
> On Friday, December 10, 2021 at 7:08:47 PM UTC-5, Lynn McGuire wrote:
>> I am porting our 850,000 lines of F77 code to the latest Intel Fortran.
>> The hidden verification of all the subroutine arguments is causing me a
>> lot of work. Plus this little code change got me when I back ported to
>> our Open Watcom F77 compiler:
>>
>> double precision factor (1)
>> ...
>> factor = qaunit / 5.44444d0
>>
>> The calculation of factor is legal for the Intel Fortran compiler but
>> not on the Open Watcom F77 compiler. Is this part of the array changes
>> in the F90 and above compilers ?
As others have pointed out, this statement is legal f90+ code because of
array syntax. Assignment of a scalar to an array broadcasts that value
to all elements of the array. In this case, the dummy array has a single
element, regardless of the size of the actual array.
This is not legal f77 code, where such an assignment was undefined. The
simple change
factor(1) = qaunit / 5.44444d0
would make that statement standard conforming with f77 and every
standard thereafter.
There is a separate issue with associating a scalar actual argument with
the dummy array, factor(1). That is not legal anywhere. It works on some
compilers because they happen to pass all arguments by address. But
historically, compilers have used various ways to associate actual and
dummy arguments, and not all of those are consistent with the rank
mismatch. For example, some compilers pass the first few scalar
arguments through registers rather than by address. In that case the
actual scalar argument value would have been loaded into a register,
used directly in the register within the subprogram, and then eventually
copied back from that register into its memory location by the calling
program. The dummy declaration would have looked for an address on the
stack for that argument instead of its value in the register, so the
compiler would not have made the correct association between actual and
dummy argument. If the compiler could not detect such errors, then
syntax tools such as FTNCHEK could detect them. Contrary to some
previous statements in this thead, this was a fairly common error in
fortran codes in the 70s and 80s, and I think most programmers were
aware of the problem, they just did not have or use the tools available
to detect and correct the code. In the above case, as I understand it,
it was a recently introduced error, not a legacy error.
Then there is a further issue with associating a scalar constant or
expression with a dummy argument that is modified within the subprogram.
That is not allowed, at all, even with a scalar dummy argument. In f77,
and with f90+ when the interface is implicit, it is up to the programmer
to ensure that does not happen. Some compilers could catch such an error
at compile time if it could see the dummy argument declarations, and
some compilers could catch such an error at run time by placing the
constant in read-only memory where the subsequent modification attempt
could be detected. Some cases cannot be detected by static analysis
because the illegal modification only occurs on some calls. In f90+ if
the interface is explicit, and if intent(out) or intent(inout) are
specified, then the compiler should catch such an error at compile time.
So it appears that there were several possible errors associated with
that single statement: rank mismatches between actual and dummy
arguments, unintentional rank mismatches within the statement itself,
and mismatches of argument intent due to the lack of an explicit interface.
$.02 -Ron Shepard