Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Array assignment semantics changed in IF 2017

Tobias_Loew
Novice
1,091 Views

The following program runs perfectly well up to (including) IF 2016. At the end of the program the array DEST contains 1 for indices 1 to 9 and 0 for all other indices. Now, with IF 2017 the program crashes (!) as it tries to assign all 80000 elements from SOURCE to DEST. I looked through the FORTRAN 95 standard but couldn't find a definite answer to that but IMHO either IF 2017 should reproduces the semantics of its predecessors or issue a compilation error but under no circumstances silently change the semantics and introduce a bug/runtime crash.

        program Console2
        implicit none
        integer*4 MAX_INDEX
        integer*4 DEST(80)
        integer*4 SOURCE(80000)
     
        MAX_INDEX = 9
        SOURCE = 1
        DEST = 0

        DEST(1:MAX_INDEX)=SOURCE

          
        end program Console2

Sorry to say that, but the Intel-FORTRAN compilers keep introducing regressions in every new version (cf. e.g. https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/675911)

0 Kudos
30 Replies
jimdempseyatthecove
Honored Contributor III
486 Views

Note, when the compiler can determine the sizes of a and b, the optimization will yield the appropriate branch without performing the test (and without generating code for the other branch). I haven't tested this, but you can, change the name "ReportBug" to "SuspiciousCopy", and make sure there is no subroutine of that name. IOW the Linker will report the error (situation).

As others are reporting to you, if the sizes cannot be determined until runtime, then you will need the ReportBug/SuspiciousCopy routine (which could simply print out the file and line number, then stop (or continue, your choice).

Jim Dempsey

0 Kudos
John_Campbell
New Contributor II
486 Views

I am puzzled by this thread. Is the problem that  "DEST(1:MAX_INDEX)=SOURCE" is illegal ?

Why doesn't the compiler simply replace this by DEST(1:n)=SOURCE(1:n) where n = min(MAX_INDEX,size(SOURCE)) ?

Wouldn't this be the response if DEST and SOURCE were character ?

I haven't been able to identify in the standard a discussion of different extent of arrays but I thought that the limiting extent would apply.

 

0 Kudos
Tobias_Loew
Novice
486 Views

@ John:I like your proposal. It would fix the problems in my code, but if I could rewrite the standard I would make it slightly different:

In case of array-assignment: If exactly one of destination or source array has an explicitly specified upper bound, then from this array the number of copied elements is derived.

This wouldn't prevent all runtime errors but it would follow the schema "explicit rules over implicit".

0 Kudos
IanH
Honored Contributor II
486 Views

John Campbell wrote:

I am puzzled by this thread. Is the problem that  "DEST(1:MAX_INDEX)=SOURCE" is illegal ?

Why doesn't the compiler simply replace this by DEST(1:n)=SOURCE(1:n) where n = min(MAX_INDEX,size(SOURCE)) ?

Wouldn't this be the response if DEST and SOURCE were character ?

I haven't been able to identify in the standard a discussion of different extent of arrays but I thought that the limiting extent would apply.

The requirement that the left hand and right hand sides of an assignment statement be conformable, unless you have an allocatable left hand side, is in F2008 7.2.1.2p1(2).

Character assignment must also meet that conformable requirement - if both left and right hand sides of the assignment are arrays, their shape must match, or the left hand side can be an array and the right hand side can be a scalar.  It is the length type parameter that is permitted to differ across an array.  The meaning of mismatch in length for character assignment is well defined in the standard - a mismatch in length is handled using blank padding or truncation.  I don't think it is as straight forward to define the meaning of a mismatch in array shape - what are you going to use as a blank padding value for an array of derived type?

 

0 Kudos
andrew_4619
Honored Contributor II
486 Views

The language constraints in this area are quite OK as they are, it is not difficult or onerous to write new code correctly to standard. If one were to change change standard to retrospectively "fix" older non-compliant code then which version of wrong would we make correct and what would get broken as a result?

0 Kudos
John_Campbell
New Contributor II
486 Views

I was not suggesting a change to the standard. It appears that I have misinterpreted the standard, as I did not identify an explicit restriction for array extent. RESHAPE offers something like what I had assumed.

The easy fix is:  DEST(1:MAX_INDEX)=SOURCE(1:MAX_INDEX)

This is a coding requirement that is common to many uses of 2 arrays, such as in the use of DOT_PRODUCT

0 Kudos
Tobias_Loew
Novice
486 Views

@Andrew_4619: I can't follow your argument to not change the standard, since the semantics of my non-standard code got broken by changing from a previous version to IF2017. I would rather like to see a compiler info/warning/error than a silently introduced runtime-error.

0 Kudos
mecej4
Honored Contributor III
486 Views

John C. and Tobias:

Please reevaluate your proposals to "fix" the standard by considering the slightly changed case where, instead of declaring

     SOURCE(80000)

we had declared

     SOURCE(-39999:40000)

In this case, how would you expect the assignment

     DEST(1:MAX_INDEX)=SOURCE

to be implemented?

0 Kudos
jimdempseyatthecove
Honored Contributor III
486 Views

>>Why doesn't the compiler simply replace this by DEST(1:n)=SOURCE(1:n) where n = min(MAX_INDEX,size(SOURCE)) ?

Also, consider the situation where the size of SOURCE is the correct size. Which result is simply correct?

Jim Dempsey

0 Kudos
John_Campbell
New Contributor II
486 Views

@mecej4 : I wouldn't !!  I probably shouldn't guess too much from the cut down sample, but isn't SOURCE a pool for the initialisation of DEST, so your declaration would not happen.

@jim : if MAX_INDEX = size(Source) shouldn't it then work as the standard requires ? Although it appears that size(Source) >> MAX_INDEX.

A correct coding could be DEST(1:MAX_INDEX)=SOURCE(1:MAX_INDEX), but it appears that older versions of ifort accepted "DEST(1:MAX_INDEX)=SOURCE" and apparently did what was required.

Cleaning out some old non-conforming interpretation, which is always a problem for old non-conforming programmers.

0 Kudos
Reply