------- Comment #14 from burnus at gcc dot gnu dot org 2008-10-28 18:56 ------- > When I run > program test > integer i > i = transfer(-1,1.0) > print *, i > end > > I get -2147483648 with gcc-4.2, ifort, and pgf90 on x86_64 Linux, and same > value with xlf on AIX with power5.
Ditto for openf95. g95 warns (integer overflow) and prints "0"; NAG f95 gives an "Error: Result of TRANSFER is Not a Number". At run time, gfortran, g95 and NAG f95 (w/ IEEE exceptions disabled) processes it and print "-2147483648". I agree with Steve that assigning NaN and INF to an integer does not make sense. What integer matches NaN - none! One can assign the bit pattern of NaN, i.e. "i = transfer(NaN, 0)" but that is something completely different and "well" defined. NAG's arithmetic exception also makes sense. Steve wrote: > In thinking about transfer(-1,1.0), this may also be invalid With Fortran 2003's IEEE support the latter should be valid (if a given "processor" supports the needed IEEE features and similar restrictions). Dominque wrote: > I think the conversion of NaN to int is buggy since the behavior is > platform/option dependent. Your patch just prevents to reach the bug. It > always make me nervous when a bug is hidden without being understood. I think such an investigation makes sense in general but for the error message "gmp: overflow in mpz type" it might not be needed: It simply states that MPFR/GMP does not like the conversion. If there are any other code paths, the patch does not make it more likely that they are hit. >From the patch: + gfc_error ("Conversion of exceptional value at %L", where); I don't like this error message - when I read it I don't understand the meaning of "exceptional". How about something like the following: - "Conversion of non-representable value (NaN or Infinity) at %L" - "Conversion of non-representable value at %L" - "Conversion of NaN or Infinity at %L" - "Conversion of Not-a-Number or Infinity at %L" or ... ? Dominique just wrote: > Is -3.40282347E+38 more valid than NaN or -Inf? I believe it is. You can convert "-3.40282347E+38" into an integer and you get: -340282347000000000000000000000000000000. You can now assign that integer to your integer variable. You probably loose some digits as the variable is too small ("overflows" but actually it is rather a cut off of digits, ignoring the sign bit for the moment). But which integer matches INF? 99999 with infinitely many trailing 9s. Or do you prefer to have 10000 with infinitely many trailing 0s. Depending what you choose and taking the last n bits you get different values for your variable. And for NaN: I frankly have no idea to what integer this is supposed to match. If you talk about bit patterns the situation is completely different. You can assign the bit pattern of NaN to any integer, real, logical etc. variable if you want. For instance transfer(-1, 0.0) is a perfectly fine real number, which you also may assign to any other real or complex number. You may also TRANSFER it bitwise to an integer number (which gives the number you started with: "-1"). But if you try to assign the number, you are in trouble (see above). ----------------------------------- >From comment 1: Adw_xabcd_8(1:n) = transfer(-1,1.0) ! Adw_xabcd_8 is REAL That makes sense: One assigns NaN to a real variable (though a comment would be helpful). However Adw_Fn_I (n) = transfer(-1,1.0) ! Adw_Fn_I is an INTEGER does not make sense as there is no NaN for integers. Here, one could have used "-HUGE(Adw_Fn_I)" or similar. I think the programmer simply missed that Adw_Fn_I is no real variable; as long as compiler digest this number it does its purpose - initializing the variable with garbage, but syntactically it does not make sense - and a compiler has all rights to reject it. -- burnus at gcc dot gnu dot org changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |burnus at gcc dot gnu dot | |org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37930