From: Richard Maine on
gmail-unlp <ftinetti(a)gmail.com> wrote:

> I was realizing that nothing in the
> standard defines or identifies an undefined variable as non
> conformant on itself,

Correct. Just to elaborate slightly: there is nothing wrong
(non-conformant) in a variable becomming undefined. It is quite normal
for variables to become undefined at various times. What is
non-conformant is referencing a variable when it is undefined.

As "undefined" basically means "does not have a value according to the
standard" and to reference a variable means "to use its value", it is
sensible that referencing an undefined variable might be problematic.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
From: Richard Maine on
glen herrmannsfeldt <gah(a)ugcs.caltech.edu> wrote:

> Some languages say something like "processor dependent" when a
> variable should have a legal, but undetermined, value. I don't
> know if Fortran has that distinction.

Yes, it does. But there is a distinction between "processor-dependent"
and "undefined". Both exist in the standard and they have different
implications.

"Processor-dependent" means (just like it sounds) that the result might
be different on different processors, but it is considered a perfectly
"legal" value. There is nothing nonstandard about referencing a
processor-dependent value. Many things are processor dependent. For but
one example, the value of iostat that indicates an end of file is
processor dependent, but of course you are allowed to reference an
iostat-retuened value, that being the main point of iostat.

"Undefined" roughly means "is not standard-conforming to reference."
There are actually multiple reasons why the standard might specify that
something is undefined. In many cases it is because, as Dan described,
different implementations are likely to give different results. The
standard could potentially specify that the result is processor
dependent in such cases. That's a decision that the committee makes and
there have been times when the committee has debated whether a
particular case should be specified to be processor dependent or
undefined. It does make a difference.

There are some cases (such as the iostat one I mentioned above) where it
is obvious that "processor dependent" would be specified; it would be
nonsense to do otherwise. I'd say that most of the other cases are
specified to be "undefined". There are a few that I consider somewhat
inconsistent. Notably, if you equivalence two variables of different
type, then defining one of them undefines the other, making it
nonstandard to use equivalence to type cheat. But if you use TRANSFER to
achieve the same ends, the result is processor dependent. In my view
this is slightly inconsistent and I would not have guessed the
distinction without looking in the standard.

Although "undefined" is often specified when different implementations
might give different results, there are other aspects of it as well. For
example, since it is illegal for a program to reference an undefined
variable, a compiler can legitimately trap such a reference as an error.
Most compilers don't, but it is a valid (and very useful) capability for
a compiler to have. Something that is undefined might have an "invalid"
bit pattern. That's not necessarily the case, but it can be so in some
cases.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
From: glen herrmannsfeldt on
Richard Maine <nospam(a)see.signature> wrote:
> glen herrmannsfeldt <gah(a)ugcs.caltech.edu> wrote:

>> Some languages say something like "processor dependent" when a
>> variable should have a legal, but undetermined, value. I don't
>> know if Fortran has that distinction.

> Yes, it does. But there is a distinction between "processor-dependent"
> and "undefined". Both exist in the standard and they have different
> implications.

> "Processor-dependent" means (just like it sounds) that the result might
> be different on different processors, but it is considered a perfectly
> "legal" value. There is nothing nonstandard about referencing a
> processor-dependent value. Many things are processor dependent. For but
> one example, the value of iostat that indicates an end of file is
> processor dependent, but of course you are allowed to reference an
> iostat-retuened value, that being the main point of iostat.

Another case is using the bit manipulation functions on values
with the sign bit '1'. As Fortran (and C) allow for radix complement,
digit complement, and sign magnitude values, the results can be
dependent on which representation is used. (C allows for all
three in base two, Fortran allows for them in any base greater
than one.)

> "Undefined" roughly means "is not standard-conforming to reference."
> There are actually multiple reasons why the standard might specify that
> something is undefined. In many cases it is because, as Dan described,
> different implementations are likely to give different results.

Well, in the case above, likely isn't quite right. It is very
unlikely that you will run into a ones complement machine, though
the probability isn't zero.

> The standard could potentially specify that the result is processor
> dependent in such cases. That's a decision that the committee makes and
> there have been times when the committee has debated whether a
> particular case should be specified to be processor dependent or
> undefined. It does make a difference.

Yes. So while the case of a function being executed an unknown
number of times, and incrementing a variable each time, would seem
to give a processor dependent result, the standard seems to indicate
an undefined result.

> There are some cases (such as the iostat one I mentioned above) where it
> is obvious that "processor dependent" would be specified; it would be
> nonsense to do otherwise. I'd say that most of the other cases are
> specified to be "undefined". There are a few that I consider somewhat
> inconsistent. Notably, if you equivalence two variables of different
> type, then defining one of them undefines the other, making it
> nonstandard to use equivalence to type cheat. But if you use TRANSFER to
> achieve the same ends, the result is processor dependent. In my view
> this is slightly inconsistent and I would not have guessed the
> distinction without looking in the standard.

Before TRANSFER this was often done because it was pretty much
the only way to do it. I can find a few ways that undefined
results should come from the EQUIVALENCE case, but TRANSFER
should give the right result. In years past there were processors
with tagged storage. Additional bits indicate the type of value
stored in a given storage location. Most likely there is a way
on such machines to do TRANSFER, but EQUIVALENCE won't do the
appropriate operation. Also, JVM, the Java Virtual Machine,
commonly used to run compiled Java code, restricts the ability
to reference storage as a different type or size. The code
verifier, which is supposed to be run before the class file
is executed, checks for such references. There are, however,
intrinsic functions that allow for something like TRANSFER.

It might be interesting to have a Fortran compiler generating
JVM code. I believe it is a little easier than doing it
from C.

> Although "undefined" is often specified when different implementations
> might give different results, there are other aspects of it as well. For
> example, since it is illegal for a program to reference an undefined
> variable, a compiler can legitimately trap such a reference as an error.
> Most compilers don't, but it is a valid (and very useful) capability for
> a compiler to have. Something that is undefined might have an "invalid"
> bit pattern. That's not necessarily the case, but it can be so in some
> cases.

Yes. As I said previously, that might happen in the case of
an I/O error, such that a READ didn't fill all the list items.
(Also, EOF before all list items were filled.) That wouldn't seem
to be the case in a function called from a possible short-circuit
logical expression evaluation, though.

-- glen
From: Dan Nagle on
Hello,

On 2010-07-19 12:53:49 -0400, nospam(a)see.signature (Richard Maine) said:

> Yes, it does. But there is a distinction between "processor-dependent"
> and "undefined". Both exist in the standard and they have different
> implications.

One item added for f08 was a list of processor dependencies.
See Annex A of N1826. It's about four pages.

--
Cheers!

Dan Nagle

From: Louis Krupp on
On 7/19/2010 12:02 PM, glen herrmannsfeldt wrote:
<snip>
> Before TRANSFER this was often done because it was pretty much
> the only way to do it. I can find a few ways that undefined
> results should come from the EQUIVALENCE case, but TRANSFER
> should give the right result. In years past there were processors
> with tagged storage. Additional bits indicate the type of value
> stored in a given storage location. Most likely there is a way
> on such machines to do TRANSFER, but EQUIVALENCE won't do the
> appropriate operation.
<snip>

Unisys MCP systems still use tag fields: 0 for single precision, 2 for
double precision. Anyone have access to a FORTRAN compiler on one of
these? It seems like this would be valid code:

implicit none
real r(2)
double precision d(1)
equivalence (r, d)

My guess is that accessing an element of d after setting an overlapping
element of r (or vice versa) would give surprising results.

I used FORTRAN on this architecture's predecessor (Burroughs Large
Systems) years ago, but I never tried doing this. (We didn't use double
precision that much, as I recall. Not enough memory, and the 39-bit
single-precision mantissa was usually good enough.)

Louis