From: Richard Maine on 19 Jul 2010 12:26 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 19 Jul 2010 12:53 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 19 Jul 2010 14:02 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 19 Jul 2010 14:34 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 19 Jul 2010 15:47
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 |