Does anyone use not() with a logical argument ?

Does anyone use not() with a logical argument ?

I have been using it for years. At first it was by accident but I found it worked fine and the code often looks easier to understand. But it seams to be broken in XE2013.

Try this code. It fails if you turn on F2003 semantics. However Premier support say not() is not supported for boolean arguments. I think it is a trap many could fall into.

If you assign not(.true.) to a boolean it actually shows correctly as false in the debugger. But the internal value is -2 which trips up the if block.

program test

implicit none

if(not(.true.))then

print*,'what am I doing in this block'

pause

end if

end program

8 Beiträge / 0 neu
Letzter Beitrag
Nähere Informationen zur Compiler-Optimierung finden Sie in unserem Optimierungshinweis.

Your code is what is broken, not the compiler. The NOT intrinsic takes an integer argument. As an extension, Intel Fortran allows you to pass a LOGICAL and then gives you a "free" conversion. As you found, this can get you into trouble.

If you compile this code with standards checking you get:

t.f90(5): warning #7056: Allowing integer arguments to be logical for this intrinsic function is not standard Fortran 2003
if(not(.true.))then
-------^
t.f90(5): warning #6188: Fortran 2003 requires a LOGICAL data type in this context. [NOT]
if(not(.true.))then
---^

In addition to passing the wrong type to NOT, you then used the integer function result in a logical IF, another error.

You want the .NOT. operator here. See Doctor Fortran in "To .EQV. or to .NEQV., that is the question", or "It's only LOGICAL" for more on this.

A bit more detail...

Up through Fortran 95, the standard did not specify the internal representation of LOGICAL values. Intel Fortran, with its history going back to VAX-11 FORTRAN-IV-PLUS of 1978, treats values with the low order bit set to be .TRUE. and values with the low order bit clear to be .FALSE.. The motivation for this was the VAX architecture and the VMS condition handling standard. If you are looking at the literal .TRUE., the internal value is -1 (all bits set) and for .FALSE., 0 (all bits clear).

Fortran 2003 still didn't say what the internal representation should be, but it does say, in the chapter on C interoperability, that the Fortran LOGICAL type interoperates with the C _Bool type. When C tests for false/true, it uses zero/not-zero and the literal true is 1 (false is 0). This implies that Fortran LOGICAL should also follow this. As it happens, we have an option, /fpscomp:logicals which changes the Fortran behavior. This was added for Digital Visual Fortran 5 in order to be compatible with Microsoft Fortran PowerStation. When you say /standard-semantics, that implies /fpscomp:logicals so that the C interoperability association works. I think what changed in the 13.0 compiler was to add /fpscomp:logicals to the set of options implied by /standard-semantics.

Steve - Intel Developer Support

An option for Intel when designing this into the compiler could have been to introduce another (second?) logical kind (C_BOOL /= 1), couldn't it?

Not a practical option, really. Especially as we already had the necessary support to meet the standard. Only incorrect programs would see a difference. Adding a new type or kind to the compiler is a lot of work.

Steve - Intel Developer Support

Zitat:

Steve Lionel (Intel) schrieb:

You want the .NOT. operator here. See Doctor Fortran in "To .EQV. or to .NEQV., that is the question", or "It's only LOGICAL" for more on this.


Interesting...

I have one question about that. Which one is correct or does the IVF compiler use .eqv. automaticly?


if(logicalValue) then

! ...

end if
if(logicalValue.eqv..true.) then

!...

end if

Markus

Those are logical expressions and are equivalent. In a logical IF, the expression in parentheses is evaluated for true/false as a logical value. Use of .eqv. here is redundant, but not harmful.

Steve - Intel Developer Support

Zitat:

Steve Lionel (Intel) schrieb:

Not a practical option, really. Especially as we already had the necessary support to meet the standard. Only incorrect programs would see a difference. Adding a new type or kind to the compiler is a lot of work.


MegaLOL. Did you have the dual sets of intrinsics in place to handle both styles of LOGICAL arguments? Correct progams can't use TRANSFER? C programmers can't correctly predict or interpret the behavior of _Bool variables, so why should Fortran programmers be expected to? If a Fortran program has LOGICAL(C_BOOL) in its specification-part it's just wrong in virtually every case. The right solution is for the compiler to set C_BOOL = -1, but I have never seen a vendor resist the urge to consume the Kool-Aid in this instance.

We have only one set of intrinsics - the option changes the behavior. As for TRANSFER, using that exposes you to implementation-dependent results.

I actually agree with you that C_BOOL should be -1.

Steve - Intel Developer Support

Kommentar hinterlassen

Bitte anmelden, um einen Kommentar hinzuzufügen. Sie sind noch nicht Mitglied? Jetzt teilnehmen