-vms flag character parameter handling differs from VMS

-vms flag character parameter handling differs from VMS

Chris Payne's picture

Compiler version is 11.1.059 on 64-bit RHEL 5.4. Here are sample programs

program m

implicit none

call sub1('X)

end program

subroutine sub1(s)

implicit none

character*8 s

write (6,*) 'sub1 s = ', s

end subroutine

We use the following compiler flags :
-check bounds
-align norecords
-align dcommons
-align nosequence
-warn declarations
-warn usage
-warn truncated_source
-warn noalign
-real-size 64
-double-size 64
-integer-size 32

When executed, this code crashes at the write statement in sub1 with error "forrtl: severe (408): fort: (18): Dummy character variable 'S' has length 8 which is greater then actual variable length 1". It should print "sub1 s = X". Disabling -check bounds it not an option. Are there other flags needed to get compatibility with HP VMS Fortran, before we take on changing the 1,193 locations in our code that will generate this crash?


9 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.
Kevin Davis (Intel)'s picture

I'm not knowledgeable about the treatment of character parameters on VMS but the error is new with the introduction of the string bounds checking provided in our 11.1 release. The program runs as you expect with Intel Fortran 10.1 and earlier compilers without -vms and with bounds checking enabled because the string bounds checks are not done.

Based on an earlier related thread (here), the advice of using CHARACTER(*) is a possible solution with the 11.1 release and bounds checking enabled. I don't see any other compiler options that may help.

Chris Payne's picture

HP Fortran for VMS uses the smaller of the lengths of the dummy and actual argument. Character*(*) has its own risks, since it exposes more of the caller's variable to the subprogram if the caller provides a longer character variable than the subprogram expects.

If I ask for an enhancement to -vms, what are my chances of getting it?


mecej4's picture

From the HP OpenVMS Fortran reference manual, Sec. 8.8:

"If a scalar dummy argument is of type character, its length must not be
greater than the length of its associated actual argument."

Another quote, this one from Sec. 6.1.1 of the Compaq Fortran 77 Language Reference Manual (1999):

"The length of a dummy argument with a data type of character must
not be greater than the length of its associated actual argument."

The VAX Fortran behavior that you describe may have existed in an old version, but is in disagreement both with the Fortran 77 standard and the just listed references for VMS Fortran.

If Intel were to implement your request, we should hope that it will be under a separate option: not the -vms option.

Chris Payne's picture

You are correct. My testing of the current HP VMS Fortan compiler was incomplete. It does overrun the string length if a shorter actual argument is provided.

Thank you for your time.

Ronald W Green (Intel)'s picture


I'd like to have Steve Lionel have a look at this issue, since he is an expert on VMS Fortran behavior. He's been out on vacation this week but will be back next week.

And to summarize: I believe you want the combination of -vms -check bounds to IGNORE string bounds checking altogether, because older VMS compilers did not check string bounds?


hirchert728's picture

With 1193 places to repair, you may not want to consider this approach, but if there is any chance this program will find its way to yet another compiler in the future, you might save yourself future work by programming the behavior you want in legal standard Fortran rather than depending on a nonstandard vendor extension (especially one that few vendors have adopted). In this case, you could change the declaration of S to from CHARACTER(8) to CHARACTER(*) and change references to S in full to S(:MIN(8,LEN(S))).

[If, in the real code, there are many references to S in the procedure, there are tricks you might apply to minimize the textual changes. For example, you might move the body of the procedure into an internal procedure, with a new host body that simply calls the internal procedure, passing through the arguments, except that instead of passing through S, you pass through S(:MIN(8,LEN(S))). The S inside the internal procedure now has the properties you were expecting of S in your original code.]

Good luck!


mecej4's picture

It is becoming more evident that we are opening Pandora's Box with this issue.

Chris, if you don't mind, please state why it is necessary for you to request bound-checks at all? Do you want bounds checked for only non-CHARACTER types? Or do you want some checking done for CHARACTER types, too, but want the specific standard-violating behavior not flagged?

There is a way out that does not call for the dubious tactic of altering the compiler merely to allow one user's non-standard-conforming code to work.

This would consist of giving the user a means to allow the Fortran runtime error handler to ignore a specific error, a certain count of errors of all types, or to demote a numbered error to a warning, the selection being made using environment variables or extra command line options to be passed to the Fortran runtime. All errors would be caught and, by default, reported, but the user would have the option to suppress/ignore a chosen subset of errors.

Steve Lionel (Intel)'s picture

The only "VMS" aspect to this is that the VMS compiler did not catch this programming error. We enhanced the Intel compiler to do so around version 11.0. The code is not legal Fortran and our compiler is correct to complain. That the VMS compiler did not catch it was not a "feature". As noted, the VMS compilers did not use the minimum of the lengths - they blindly accepted the declared length.

The appropriate fix here is to use CHARACTER(*) rather than an explicit length for a character dummy argument. We will not change the compiler to remove this error check as part of bounds checking.


Login to leave a comment.