Software Archive
Read-only legacy content
17061 Discussions

Perils of Upgrading

Deleted_U_Intel
Employee
604 Views
Recently we struck a compiler bug (an issue I raised here a couple of weeks ago). We were advised to u/g from 6.1A to 6.5A to cure the problem. Indeed it did.

BUT - just hours from a submission deadline, we now discover a new problem. ie.

In a subroutine that is entered several times (once for each year analysed), there is a derived type, which has its elements initialised to "zero" (variously 0, 0.0, & ' ') in the TYPE declaration. In the 6.1A version, the declaration reinitialised the variables of that type to zero each time the subroutine was entered, but alas (though maybe correctly) in 6.5A, the variables retain their values between calls to the subroutine.

One wise sage in our team has resisted upgrading to 6.5A to date, so we have been able to confirm that the change in behaviour is due to the u/g. ie. same source code behaves differently when compiled in 6.1A cf. 6.5A.

I do not recall seeing anything about this in the release notes, though I readily confess that my concentration may have drifted as I waded through several hundred (thousand ?) generally obscure changes noted there.

Maybe the behaviour under 6.5A is how it is supposed to work ?

BUT - I would have thought this a MAJOR change that warranted HIGHLIGHTING in a BIG way - right up front.

This is a large program with multiple outputs - it takes a while before all of them get checked (depending on which outputs particular users are most interested in & on what types of analysis are done).

The resulting error in the output has only just been discovered in the nick of time. A day later & it could have been highly embarrassing.

Unfortunately the fix is not straight forward. Since all seemed well (& exe submitted), I decided to insert a new component (the bit affected by the compiler bug) into the source code. As a result the source is "under construction" & in no state to be recompiled. Saved only by the stray 6.1A compiler.

The perils of programming for sure, but I feel that changes of this type should be given considerable prominence. It could take a long time to find all the consequences. Does not inspire confidence. What other consequences still lurk in the dark, as yet undetected ?

David
0 Kudos
7 Replies
Jugoslav_Dujic
Valued Contributor II
604 Views
Which way are you initializing those derived-type variables? Using constructors, like:

a)
TYPE(T_MYTYPE):: tMT=T_MYTYPE(0., 0, '')


or

b)
TYPE(T_MYTYPE):: tMT 
tMT=T_MYTYPE(0., 0, '')


If a) CVF 6.5 behaviour is correct. You can find all such occurences -- I think -- by switching on "Variables default to AUTOMATIC" for one by one source file or for entire project (also increasing allowed number of error messages generated by the compiler) and building/compiling. Since AUTOMATIC variables may not be initialized using DATA statement (which is equivalent to a)), you'll get compiler errors for each uninitialized variables. After fixing those, switch off "default to AUTOMATIC"


Another solution may be to switch on "Fortran Standard Checkings" in "Fortran Language" section of project settings. If you did not use too much extensions, you'll get warnings for use of constructors (I think).

If you used b), well, it looks like a 6.5 bug.

Steve will probably comment on the rest.

Jugoslav
0 Kudos
Steven_L_Intel1
Employee
604 Views
The 6.5A behavior is correct - variables with initialization are implicitly SAVEd, per the standard, and retain their values across calls to the routine. Fortran has no concept of run-time initialization other than putting it yourself in the code.

Steve
0 Kudos
durisinm
Novice
604 Views
Steve,

You wrote that initialized variable values are automatically SAVEd "per the standard." I always thought that Fortran 77 did *not* SAVE a variable's value in a subprogram between calls unless the programmer explicitly coded a SAVE statement for it (although many compilers automatically SAVEd all variable values). Did that rule change in Fortran 90 and 95, or has Fortran 77 always SAVEd initialized--but not uninitialized--variable values?

Mike Durisin
0 Kudos
Steven_L_Intel1
Employee
604 Views
Mike,

Yes, Fortran 90 has explicit language saying that initialized variables have implied SAVE semantics. To quote, "The presence of initialization implies that object-name is saved, except for an object-name in a named common block or an object-name with the PARAMETER attribute. The implied SAVE attribute may be reaffirmed by explicit use of the SAVE attribute in the type declaration, or by inclusion of the object-name in a SAVE statement." (Fortran 95, section 5.1, page 49, lines 22-25)

But... and I should have looked this up before responding to David earlier, this statement does not apply to initialization in a derived type definition. This is called component initialization. Here, the standard says that SAVE is not implied, though the standard doesn't say that a compiler can't apply SAVE semantics if it wants to. The only case where it is clear that the derived type variable must be reinitialized is when the variable is an INTENT(OUT) argument, and in this case, CVF correctly reinitializes the argument on each entry.

However, there are some aspects of component initialization of local objects that I am unsure about, and will discuss with our standards representative to get his take on it. I'll report back on what I learn.

Steve
0 Kudos
Steven_L_Intel1
Employee
604 Views
OK - looks as if we have a bug here. Component initialization is supposed to be redone on each entry to the routine - which is astonishing because this is asymmetrical with the way initialization works elsewhere in Fortran. We'll fix the bug.

Steve
0 Kudos
Intel_C_Intel
Employee
604 Views
Hi Steve,

After reading your 4/25 post, I looked in the LRM under Data Types, Constants, and Variables | Derived Data Types | Default Initialization and it stated, 'Default initialization applies to dummy arguments with INTENT(OUT). It does not imply the derived-type component has the SAVE attribute.' So I thought that this may be a bug, but I was a bit confused by the documentation (particularly the intent(out) comment and how it related to the next statement) so I looked up this morning in two other sources.

Brainerd et. al.'s Fortran 95 Handbook states in section 5.6.4, 'Any object that is data initialized (in a DATA statement or a type declaration statement) has the SAVE attribute by default. However, a structure of a derived type for which any component has been default initialized does not have the SAVE attribute.'

Metcalfe and Reid's Fortran 90/95 Explained, 2nd Ed states in section 7.5.4, 'Unlike explicit initialization in a type declaration or data statement, default initialization does not imply that the objects have the save attribute. However, an object of such a type that is declared in a module is required to have the save attribute unless it is a pointer or an allocatable array. This is because of the difficulty that some implementations would have with determining when a non-saved object would need to be re-initialized.'

So, I guess I'm still a bit confused. Can your standards rep, or the good Dr. himself :), provide a bit more insight? Is M&R's comment wrt modules represented in the standard or is it just their recommendation? Should I cross post this to c.l.f.?

TIA,
John
0 Kudos
Steven_L_Intel1
Employee
604 Views
The description in Brainerd, et al, is correct and is a condensation of what the standard says. The M+R comment is interesting, and may have derived from ambiguous wording in Fortran 90. (I'm writing this at home and have only the F95 standard to reference.) F95 is unambiguous that the M+R comment does not apply. The applicable reference is 14.7.5, Events that cause variables to become defined, subitem (19), "Invocation of a procedure that contains a nonsaved local object that is not a dummy argument, is not accessed by use or host association, has neither the ALLOCATABLE nor POINTER attribute, and is of a derived type in which default initialization is specified for any direct components, causes those components of the object to become defined."

What is interesting about this, and supports the M+R comment as a recommendation, is that if you return from a routine that references such a variable, the rules in 14.7.6 (Events that cause variables to become undefined) say that the variable becomes undefined unless it "also is referenced directly or indirectly by at least one other scoping unit that is making either a direct or indirect reference to the subprogram." The standard, however, doesn't say (that I can find) that you shall give such objects the SAVE attribute.

Putting these two together, you can't depend on the module derived type variable becoming defined on entry, because it's "accessed by use or host association", but it can become undefined on exit. Very amusing. Let me see what Stan (our standards rep) has to say about that!

Steve
0 Kudos
Reply