More about "compiler bug" mentioned earlier

More about "compiler bug" mentioned earlier

I was mistaken when I said that it was not setting up the arguments properly.

It was actually the DEBUGGER that is screwed up.

It can't display ANY REAL*8 variables, it gives NONSENSE values for those.

I am wondering though -

They know that this debugger is going to be used by scientists and engineers, so why won't they

address the issue of REAL*8  or REAL*16 variables? Are they assuming only C programmers will use it?

I had to make the subroutine (Drawcirc) earlier SEPARATE rather than using the CONTAINS feature, to make the program work properly.

For some reason the graphics library cannot handle that situation.

15 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

The debugger does support REAL*8 and REAL*16 variables. I'll take a look at your other thread on Monday.

Steve - Intel Developer Support

This illustrates the problem more easily. It's a simple test case running the subroutine that gave
the problems I mentioned.

Oddly enough, this same test case runs FINE with an earlier build of Fortran I have on another computer.
Now if you set a breakpoint at the beginning of the PLOT routine, and have it run that first DO LOOP
ending at about line 29, set the breakpoint there, and take a look at the values of the CC array. I saw them as garbage.
Obviously they should be between -1 and 1, since its a TRIG routine that generated them.

That DO loop should only run once, but the CC array values are all wrong. Probably why the
circles don't draw properly.

I am wondering if something subtle was done to the newer build I have build 13.05, I believe on this computer.

Other REAL*8 values look OK however.
Then the graphics program does not draw the circles every 64th call,, it only draws the dots.

Am I doing something subtly wrong?
But as I said earlier, the program runs FINE with an earlier Fortran package.
I could NOT upload the INCLUDE file. It has in it:
parameter nstate=6,maxplan=8, nplan=6

Why don't you allow that? Isn't that part of the program set as well?


Downloadapplication/octet-stream test08.f90451 bytes
Downloadapplication/octet-stream plot.f901.97 KB

I haven't run your code (don't have all the files), however in lookint at test08.f90

real*8 x(6,20)
do iang2=0,huge(iang2) ! circles march CCW
do iang=1,6 ! hexagonal array
enddo ! iang

x(3:6,7:20) is uninitialized data

In looking at plot.f90

! store pos to be erased later

You are copying uninitialized data.

As to if this is an issue or not (e.g. what happens when uninitialize data is NaN) I cannot say.

To fix this programming faux pas

real*8 x(6,20)

x = 0.0D0 ! wipe array

Jim Dempsey

I already knew about the "uninitialized data." An array usually is set up with all zeros
by default, right?

But that isn't the problem I am addressing here.
The code I am inserting at lines 24-29 only gets executed ONCE, when the routine is first called.
I didn't want to set up the CC array every time, for obvious reasons.
It does not set up that array properly, and when I display the values, those are junk.
I will put in a print statement, to see if the values are really junk. They are supposed
to be points on a unit circle. The POLYGON_W routine apparently is not getting the right numbers.
As I said before, in an earlier build of FORTRAN, the numbers are OK. Could it be the
library routine itself?

I should not have to say USE IFQWIN in the CONTAINed routine, right? It knows where to
"find" the array, I assume.

Use a ZIP file to upload multiple files or those with file types not accepted. I will ask that .inc be added to the list, but there isn't as universal a convention for Fortran includes as there is for C.

Steve - Intel Developer Support

Actually, I found a way to FIX the problem - - -
I made the CC array STATIC.
Apparently the compiler DOES NOT KEEP the same storage elements
around as I assumed, when the routine is called again.
I don't see why that issue didn't come up with an earlier Fortran version, though.
I still get garbage values displayed from the debugger. I will try to make the
CIRC array static also, even though it gets regenerated every time.
But still I get junk values from the debugger

Probably unrelated to any debugger issues, but...


I already knew about the "uninitialized data." An array usually is set up with all zeros by default, right?

No, unless you are relying on some compiler extension.

Some choices made by the compiler writers may result in zero initialisation of things being a repeatable consequence of their particular implementation, but you shouldn't rely on that for robust and portable code. Change compiler, compiler version, day of the week or underpants, and things may turn out different.


I made the CC array STATIC.

Should you be using SAVE instead of STATIC?

SAVE is the standard way of saying "please retain values between calls".

STATIC is an extension (that I'll admit I've never used) that nominates where the variable is to be stored (that choice may then give the appearance that the variables have been saved - and in a similar manner the appearance that variables have been zero initialised).

It's trivial to specify both the save attribute and zero initialise in a standard conforming way...

real(8) :: cc(2,20) = 0.0

Because the initialisation ("= 0.0") appears, the cc array above is automatically given the save attribute by the rules of the language (you can pop an explicit SAVE attribute in there for that variable too, for clarity, if you want).

I generated a simple test case (see upload) the illustrates all three types:
I observed that:
(1) The array A starts off with all zeros, even when I don't specify it.
(2) all three arrays (A,B,C) save their values between subroutine calls
run this, you'll see what I mean - - -

So it isn't clear to me that the SAVE attribute really has any useful purpose
Or maybe it does for single value quantities, as opposed to arrays?
I added two other variables D1 and D2. The value of D2 gets saves between calls, even when I don't specify that,
but D1 does NOT get saved. It is exactly the same each time, although it's garbage every time.


Downloadapplication/octet-stream test09.f90504 bytes

The compiler's default is "auto-scalar", which means that scalar variables are allocated "on the stack", so they don't retain values across calls, but arrays are allocated statically so that they tend to do so. You should not depend on this. Use of options such as OpenMP, or RECURSIVE changes this behavior. If your code requires values to retain their definition across calls, use SAVE. Some older compilers, including CVF, made all variables SAVE by default, but Intel Fortran does not.

Steve - Intel Developer Support

Hi Steve;

I added two scalar variable, one gets saved and the other does NOT.
Go figure :<( :<(

There's a difference between an "accidental" consequence of how the compiler implements things, and what you specify (via your program's source) must happen. If I modify your program slightly (introduce another call)...

      program test09

      do ! forever

        call somethingelse

        call sub1


      end program
      subroutine sub1()

      real*8 a(2,20)

      real (kind=8),static::b(2,20)=3.D0

      real (kind=8),SAVE  ::c(2,20)=5.D0

      print *,a(2,2),b(2,4),c(1,6)

      read (*,*)




      subroutine somethingelse

      end subroutine somethingelse

and compile with slightly different settings...


>ifort /Qopenmp /Od test09.f90

Intel(R) Visual Fortran Compiler XE for applications running on IA-32, Version Build 20121008

Copyright (C) 1985-2012 Intel Corporation.  All rights reserved.
Microsoft (R) Incremental Linker Version 10.00.40219.01

Copyright (C) Microsoft Corporation.  All rights reserved.







  9.346029998203773E-307   3.00000000000000        5.00000000000000
  0.100000000000000        3.25000000000000        5.12500000000000

forrtl: error (200): program aborting due to control-C event


  1.735400485756454E+261   3.00000000000000        5.00000000000000
  1.735400485756454E+261   3.25000000000000        5.12500000000000

forrtl: error (200): program aborting due to control-C event

Clearly a isn't being initialised to zero - it is just picking up some (random!) garbage present in memory.

(Note both b and c are SAVEd - c explicitly while b has an initialiser which automatically implies SAVE.)

IanH, great example.

FWIW - What you see (relating to assumed initialization) in Debug Build is not necessarily what you see in Release Build. e.g. Uninitialized variable checks initialize variables and flags to values for test.

Jim Dempsey

But isn't there a difference between something which is INITIALIZED and something which is SAVED?
You might want the subroutine to be able to access a set of constants which are available every time
it's called, rather that just saving updated values.

In other words the SAME SET of constants each time it's called.
real (kind=8)::A(3,2)=(1.5,2.3,-1.9,3.4,5.4,6.5)
Or would I use slashes rather than ()?
Now maybe my program would want to start with these numbers every time it's called - - -
Even though they are modified later on.
So I didn't put SAVE.

It would be nice to have a comprehensive article about this,
with copious examples.

I would suggest that you want to use PARAMETER constants instead of variables, SAVE or otherwise.

You are correct that there is a difference between SAVE and initialized. Giving a variable the SAVE attribute does not initialize it - SAVE means that whatever definition status a local variable had when the routine exited, that same status is in effect when the routine is reentered.

Do not make the mistake in assuming that SAVEd variables are initialized by default, even if you see what you think are initial values (such as zero.) You may be observing a side-effect of implementation, not something by design.

Steve - Intel Developer Support

Leave a Comment

Please sign in to add a comment. Not a member? Join today