------- Comment #3 from burnus at gcc dot gnu dot org  2009-06-24 13:45 -------
I think the problem relates to what is regarded as TRUE and what is regarded as
FALSE by the compilers (the following output has been produced by
transfer(.true.,0), transfer(.false.,0)):

  gfortran has: .true. =  1, .false. = 0
  ifort    has: .true. = -1, .false. = 0

For
   print *, lsame()
the libgfortran library has
   (int)logical_value ? 'T' : 'F'
and thus all non-zero values are TRUE.

However, for
   print *, .not.lsame()
there is first a .not. applied in the produced assembler. As the logical (Bool)
type is used, it is assumed that only "0" and "1" can appear as values, which
makes it simpler to .NOT. the value. However, if "-1" is passed .NOT. won't
work.

Example using

print *, i,': ', transfer(i,.true.), &
      .not.transfer(i,.true.),transfer(.not.transfer(i,.true.),0)

For gfortran:
           1 :  T F           0
           2 :  T T           3
           3 :  T T           2
  2147483647 :  T T  2147483646
           0 :  F T           1
          -1 :  T T          -2
          -2 :  T T          -1
          -3 :  T T          -4
 -2147483648 :  T T -2147483647

For ifort 11.1:
           1 :  T F          -2
           2 :  F T          -3
           3 :  T F          -4
  2147483647 :  T F -2147483648
           0 :  F T          -1
          -1 :  T F           0
          -2 :  F T           1
          -3 :  T F           2
 -2147483648 :  F T  2147483647

 * * *

> If I use gfortran 4.2.0, the logical results are correct.

I think the boolean optimization was not yet done in older GCCs; with GCC 4.1.3
it thus works. Iget .not.(-1) = 0, but with 4.2.1 I get .not.(-1) = -2

> Change of Intel compiler version ( 9.1, 10.1 were tested ) doesn't affect
> result.

For completeness, I think it also works with ifc 7.1
   (i.e. ifort < 8.0 / before the Compaq compiler merge).

 * * *

Actually, both the GCC and the Intel Compiler use the same optimization
regarding true/false for logical variables. For both -1 and 1 one only needs to
flip a bit to go from .true. to .false. and vice verca. When using the integer
check (value != 0), the assembler code becomes longer/slower.

ifort uses: "odd integer values (low bit one) are treated as true and even
integer values (low bit zero) are treated as false."


Solution: I do not see a general solution, but I am open for suggestions.

On the ifort side: "-fpscomp logicals" fixes it, but makes the code a bit
slower.

I think there is no GCC flag, which forces booleans to be treated like
integers.

 * * *

GNU Fortran bug (1): Maybe one should note in the documentation somewhere the
value of and problems with .true./.false.

(2) One could think of getting libgfortran compatible with the boolean-handling
in the middle end.


-- 

burnus at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |steven at gcc dot gnu dot
                   |                            |org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40539

Reply via email to