Operating System - OpenVMS
Showing results for 
Search instead for 
Did you mean: 

%val in Fortran

Go to solution
Bob S._1
Occasional Contributor

%val in Fortran

We recently recompiled some old code (last compiled in 2004), that contained something like the following:


WRITE(6,20) %val(xyz)

The compiler message says that "%val" is invalid in this context.

Is "%val" now only valid as a parameter to system calls?

When did this become invalid? Any other issues I should know about?

Old compiler - Digital Fortran 77 V7.1-107
Current compiler - HP Fortran V 7.6-3276
David Jones_21
Trusted Contributor

Re: %val in Fortran

I think the valid context is function and subroutine arguments, not just system calls (e.g. calling functions written in C).

What were the semantics you were expecting for that usage of %val? Were the earlier compilers in essence using the print arguments in internal function calls so %val forced treating the contents of xyz as a pointer to an integer*4? Current FORTRANs have the POINTER type, so you don't need that kludge.
I'm looking for marbles all day long.
Robert Gezelter
Honored Contributor

Re: %val in Fortran


I concur with David: what is the intended use of the result of the %val? A WRITE statement parameter would output the contents of the variable, e.g.:

XYZ = 879

should produce an output of "879". Using the %val would, if allowed, use the contents of XYZ as a pointer. This would be an unusual usage (%val, %ref, and similar qualifiers are intended to be used to enable cross-language calls). What is the contents of XYZ?

- Bob Gezelter, http://www.rlgsc.com
Bob S._1
Occasional Contributor

Re: %val in Fortran

I inherited this code (written in the late 80's), so I can't say why this was used. Using the old compiler, "WRITE(6,20) %val(xyz)" produced the same results as "WRITE(6,20) xyz".
Steven Schweda
Honored Contributor

Re: %val in Fortran

> Using the old compiler, [bad code] produced
> the same results as [good code].

This should be considered as a miracle, good
luck, or the result of using a lower-quality
compiler. If the use of %val() makes no
sense (as it does here), then rip it out.
John Gillings
Honored Contributor

Re: %val in Fortran


Interesting! the syntax:

WRITE(6,20) %val(xyz)

has always been invalid. As documented, %VAL, and its bretheren %REF and %DESCR are only valid as actual arguments in a subroutine or function call. They are used to override the default passing mechanism for the data type of its argument. %VAL is valid in any actual argument list (not just system calls, but in practice it's usually only necessary in calls to routines written in other languages).

I've confirmed your observation that some old compilers accepted your code. That was a bug! %VAL makes no sense in this context. As you've noted, the %VAL is a NOOP - the result of the WRITE statement is to write the value of XYZ. Similarly replacing %VAL with %REF or %DESCR using the old compiler makes no difference to the output. This makes me think that the compiler was simply ignoring built in functions in I/O lists. That bug has obviously been fixed in more recent compilers.

Unfortunately for you, compilers do NOT guarantee upward bug for bug compatibility. Now that the compiler bug has been fixed, the bug in your code has been revealed, so you have to fix it... sorry.

>Any other issues I should know about?

Difficult to say. Compilers guarantee upwards compatibility of correct code.
A crucible of informative mistakes
John Gillings
Honored Contributor

Re: %val in Fortran

Curiouser and Curiouser...

After some digging, I found the following release note for VAX Fortran dated 26-Jun-1995

"V6.3-150: The compiler now correctly disallows in all cases the use of the %REF, %VAL and %DESCR built-in functions outside the context of an actual argument"

How come the bad behaviour is still apparent in an Alpha compiler released in 1997? Good question, but we'll probably never know the answer. The point is it's now been fixed in the Alpha compiler, and the VAX release note proves that it's intentional.

So bottom line answer is the same. Please fix your code.
A crucible of informative mistakes
Barry Alford
Frequent Advisor

Re: %val in Fortran

(Just my £0.02 ... )

You can use for %VAL for dereferencing an address in a sharable image given by LIB$FIND_IMAGE_SYMBOL e.g.

integer*4 status, address
integer*2 i
status = LIB$Find_Image_Symbol("mySharedIimage", "mySymbol", address, ...)
i = get_int2_at(%VAL(address))

You can dereference the address thus:

integer*2 function get_int2_at( address )
integer*2 address

get_int2_at = address

Thus you can make Fortran as dangerous as C !!