Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Beginner
10 Views

Array assignment semantics changed in IF 2017

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
Highlighted
Valued Contributor II
7 Views

This does not have anything to do with a change in semantics. The program is not standard-compliant. The fact that it ran "correctly" with previous versions of the compiler does not mean it was correct.

The only thing you can accuse the compiler of is not flagging the problem at compile time.

Array assignment assume that the left-hand side has the same number of elements as the right-hand side and that is clearly not the case here. While it is easy to spot the mismatch in this program, it is not in general. But for that you have compile options to check the array bounds.

0 Kudos
Highlighted
7 Views

It's worse than "not standards compliant", the program is simply wrong. Unfortunately, our compiler does not yet offer a "shape checking" option, but this is being looked at for a future release. 

0 Kudos
Highlighted
Beginner
7 Views

@Arjen: What compile-time option are you talking about? Since I've got to maintain several 100000 LOC it would be great to check for such non-standard constructs.(If I understood Steve comment correct, there doesn't exist such an option.)

0 Kudos
Highlighted
7 Views

It's not a "non-standard construct" - it's just wrong. You could try enabling bounds checking but it would probably not catch this.

0 Kudos
Highlighted
Valued Contributor II
7 Views

The option /check:bounds - it checks whether the program gets beyond the boundaries of the entire array, but as Steve said, the compiler does not support checks on the _shape_ yet.

0 Kudos
Highlighted
Beginner
7 Views

I totally agree that non-standard code is a bad thing, but what are then all the compatibility options for in the compiler if not trying to resemble some old non-standard behavior?

@Steve: I would really appreciate a warning in case the compiler can't guarantee the same shapes for an assignment

0 Kudos
Highlighted
7 Views

In this case, it was entirely random which side's shape it would pick for doing the transfer. There was no deliberate change and the result was unpredictable.

As I noted, we're working on adding optional run-time shape checking. In the code you showed here, the compiler really has no opportunity to catch this at compile-time.

0 Kudos
Highlighted
Beginner
7 Views

Please also add a compiler warning in case of standard behavior can't be ensured. A run-time check is too late since my program then will be crashes on a customers computer.
 

0 Kudos
Highlighted
7 Views

No compiler warning in this case would be possible. The behavior is entirely dependent on the run-time value assigned to the array index.

I would hope that you do extensive in-house testing of your application. There are many, many things that cannot be checked at compile-time.

0 Kudos
Highlighted
Beginner
7 Views

The problem is: I don't no where in the code such constructs are used.

And, of course a compiler (NOT runtime) warning can be issued, e.g.

warning: array-sizes are runtime-dependent, non-standard behavior may occur [file + line information]

I don't see the point in testing all the code for finding something, that the compiler could simply tell me.

0 Kudos
Highlighted
Black Belt
7 Views

Unless you turn optimization off, in the test code DEST is not used after the erroneous assignment statement, so the whole line can be skipped after optimization.

Compilers that focus on optimization, such as Intel Fortran, may not be sufficient tools for trapping errors such as yours. We should not expect that the behavior of non-conforming code remains unchanged with new releases of the compiler, or even with different compiler options.

It is not so obvious that the error in your code can be caught at compile time rather than run time. The subscript expression on the left depends on the variable MAX_INDEX, which was changed/set a few statements earlier. In general, it would be non-trivial for the compiler to know that on Line-11 the value of MAX_INDEX is the constant value that was assigned elsewhere (Line-7). What if MAX_INDEX was a module variable, or could have been changed in a subroutine call between the two lines concerned?

Silverfrost Fortran gave the following run-time message with your code:

Run-time Error
Error: Nonconformant arrays
 main -  in file tobias.f90 at line 11 [+00cc]
0 Kudos
Highlighted
Beginner
7 Views

@mecej4: Thanks for the detailed explanation. But the code above is just a minimal test-case, so optimization is not the point at all. What I want is simply a warning/information in exactly the case you described, namely when the compiler can't ensure the arrays on both side to have the same size.

What's wrong about demanding the compiler to help the programmer to produce standard conformant code in the first place in stead of blaming him in front of his customers by producing runtime-erros, since obviously the compiler knows that the code may be executed in a non-standard manner.

By the way: I wouldn't know any FORTRAN primitives to catch/handle such a runtime-error.

0 Kudos
Highlighted
Black Belt
7 Views

Tobias,

I am sympathetic to your point of view, but I think that you attribute powers to the compiler that it does not possess when you state

"obviously the compiler knows that ...".

In the case of your program, it could know that the two sides are of different sizes if it did a static whole program analysis, but static analysis is done by a dedicated program in Intel Parallel Studio.

I agree that, if checks are requested, the compiler should help you to spot such problems, preferably at compile time, or at least at run time. It would, however, be undesirable to expect or even let the compiler fix erroneous code by replacing it with correct code representing its notion of what the programmer intended.

We tried the NAG 6.1 compiler on your program with the -C option. It did not give any error messages at compile time, but did give a run-time error:

Runtime Error: tobias.f90, line 11: Rank 1 of SOURCE has extent 80000 instead of 9
Program terminated by fatal error

0 Kudos
Highlighted
Beginner
7 Views

I don't want to insinuate the compiler holding back information. I only want the compiler to admit that it DOESN'T KNOW (whether the arrays sizes will always be equal) by printing out a warning/information.

0 Kudos
Highlighted
7 Views

A warning of that nature would be emitted for about half the lines in any reasonable Fortran program - a situation that would clearly be unacceptable to the majority of our customers.  Even A=B+C might theoretically overflow or underflow - should the compiler warn about that too?

Realistically, this is what application testing is for. As I said earlier, run-time shape checking would catch this error. Some other Fortran compilers have this, we will eventually.

0 Kudos
Highlighted
Black Belt
7 Views

Tobias Loew wrote:

I only want the compiler to admit that it DOESN'T KNOW (whether the arrays sizes will always be equal) by printing out a warning/information.

As Donald Rumsfeld taught us, there are known unknowns and unknown unknowns. It is only the former class that the compiler can have a hope of catching.

If such a feature is available in a compiler, it should be activated only if a user requests it, because otherwise one may see annoyingly voluminous warnings/error messages.

0 Kudos
Highlighted
Beginner
7 Views

@Steve: That's a fair point. Nevertheless, most of the arrays-sizes/subscript-triple are rather easy/short expressions which could be algebraic analyzed by a tool. So, my question is: do you know of any such tool, which can do such a static analysis of FORTRAN programs? Or if not, does there exists a tool which can produce an AST (abstract syntax tree) from a FORTRAN program? (Then I could write my own tools to analyze it.)

0 Kudos
Highlighted
Black Belt
7 Views

$ ifort -check -traceback tl.f90

$ ./tl
forrtl: severe (408): fort: (10): Subscript #1 of the array DEST has value 81 wh
ich is greater than the upper bound of 80

Image              PC                Routine            Line        Source

tl.exe             00007FF72F224229  Unknown               Unknown  Unknown
tl.exe             00007FF72F2211D4  MAIN__                     11  tl.f90
tl.exe             00007FF72F24CA0E  Unknown               Unknown  Unknown
tl.exe             00007FF72F24D2C5  Unknown               Unknown  Unknown
KERNEL32.DLL       00007FFF400813D2  Unknown               Unknown  Unknown
ntdll.dll          00007FFF424754E4  Unknown               Unknown  Unknown

Perhaps the wording could be improved.  Feature request?

 

0 Kudos
Highlighted
7 Views

https://github.com/CodethinkLabs/ofc claims to be a Fortran parser useful for writing such tools. I've never heard of an existing tool that would recognize the issue you described here, and I'd think that you'd be overwhelmed with false-positives if you tried.

0 Kudos