Logical Expression Oddity.

Logical Expression Oddity.

I discovered that a colleague had used a non-standard logical expression in a program, but that it had compiled and run without complaint (whether it ran correctly is another matter).
The logical expression was of the form: i > j > k

So I wrote the code fragment below and it compiled and ran successfully (CVF 6.6B) with the annotated results:

 integer*4 i, j, k
logical*1 Result
                               !        Result
i = 2; j = 3; k = 4            ! Expected    Actual
Result = i < j < k             ! .TRUE.     .TRUE.
Result = i > j > k             ! .FALSE.    .FALSE.
i = 2; j = 3; k = 2
Result = i < j < k             ! .FALSE.    .TRUE.
Result = i > j > k             ! .FALSE.    .FALSE.
i = 4; j = 3; k = 4
Result = i < j < k             ! .FALSE.    .TRUE.
Result = i > j > k             ! .FALSE.    .FALSE.

I can see that it is well worth avoiding such expressions, but I am concerned that the compiler does not pick them up as illegal. Could somebody please explain this?

The

Code

HTML tags (with square brackets) do not seem to work for me today, so apologies if the code is not so easy to read.

Alan

16 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

This is a CVF extension which allows free mixing of LOGICALs and INTEGERs. If you switch on "Fortran Standards Checking:f95" in "Compilation Diagnostics" category of Project Settings, these statements will be tagged as illegal.

HOWEVER, these statements do not even mean the obvious. Numerical value of .TRUE. in CVF is 0xFFFFFFFF (=-1), and value of .FALSE. is zero. Thus, e.g:

i = 4; j = 3; k = 4
Result = iResult = i>j>k = (i>j)> k = (-1)> 4 = .FALSE.

HTH
Jugoslav

Jugoslav www.xeffort.com

Jugoslav,

Many thanks for explaining this - I don't think that I will use ths CVF extension except in desparation because its meaning is counter-intuitive.

Alan

It's fine for bitwise operations, e.g.

iWindowStyle = (WS_OVERLAPPEDWINDOW .or. WS_CLIPCHILDREN .or. WS_BORDER .or. WS_WHATEVER) .and..not. WS_THICKFRAME

is much more succinct and readable than

iWindowStyle = IAND (IOR(WS_OVERLAPPEDWINDOW, IOR(WS_CLIPCHILDREN, IOR(WS_BORDER,WS_WHATEVER)))), NOT( WS_THICKFRAME))

Also, I abuse it when API functions return a LOGICAL but the result is not of interest -- I usually assign it to a dummy integer, so that I don't have to remember whether the function returns a LOGICAL or an INTEGER. Other than that, the usability of extensions looks doubtful.

Jugoslav

Jugoslav www.xeffort.com

Jugoslav:

I have difficulty
(1)in differentiating between a CVF Fortran logical and a C/C++ bool;
(2)in understanding why CVF Fortran logical comes in four kinds.

Any suggestions? Thanks
Gerry T.

1) It's more or less the same thing. C++ "bool" was introduced relatively recently (IIRC in 90s). IIRC true has value 1 and false has value 0. Fortran standard defines the behaviour, but not the contents of LOGICALs. CVF implementation is that only LSB is checked for evaluating the logical-valued expression:

LOGICAL:: b1, b2
b1 = 6  !Forbidden by the standard as explained above
b2 = 7
WRITE(*,*) b1, b2  !Outputs "F T"

It is as good as any (another way, IMHO bit more logical, could be that 0=.FALSE. and everything else =.TRUE.).

2) Well, they are of four different byte sizes, aren't they? You can spare space by using smaller sizes, but the performance will be slightly improved, and compatibility issues smaller, if you stick to default LOGICAL (4 bytes).

Jugoslav

Jugoslav www.xeffort.com

> 1) It's more or less the same thing. C++ "bool" was
> introduced relatively recently (IIRC in 90s). IIRC
> true has value 1 and false has value 0.
> Fortran standard defines the behaviour, but not the
> contents of LOGICALs. CVF implementation is that only
> LSB is checked for evaluating the logical-valued
> expression:

> LOGICAL:: b1, b2
> b1 = 6 !Forbidden by the standard as explained
> above
> b2 = 7
> WRITE(*,*) b1, b2 !Outputs "F T"

But in CVF, .true.=-1 and .false.=0 whereas with LSB one would expect .true.=1 like C++.

> It is as good as any (another way, IMHO bit more
> logical, could be that 0=.FALSE. and everything else
> =.TRUE.).

I agree.

>
> 2) Well, they are of four different byte sizes,
> aren't they? You can spare space by using smaller
> sizes, but the performance will be slightly improved,
> and compatibility issues smaller, if you stick to
> default LOGICAL (4 bytes).

Byte, like Dave, a a 4-letter word in Fortran. No matter, as LOGICAL is T or F, I see why there's no SELECTED_LOGICAL_KIND like the corresponding _INT_, _REAL_, and _CHAR_ intrinsics. I guess the default LOGICAL is fine whatever its KIND.

Thanks for the clarification.
Gerry T.
>
> Jugoslav

CVF's implementation of LOGICALs derives from VAX Fortran - the VAX had instructions for branching on low bit clear (or set), making the test easy. (A test for zero or non-zero would require two instructions.)

-1 is used as it is ".NOT. 0"

Steve

Steve

To Gerry: SELECTED_LOGICAL_KIND appears to be an ommission in F95 standard. It was mentioned in c.l.f. recently (I found it in a Jan Vorbrueggen's post of Jan 16). I think it is added in F2k, but at the moment I don't have the draft at hand to check it.

Steve, I'm not familiar with PC assembly, but I'd expect that zero/non-zero test takes one instruction, but LSB test takes two. Am I right?

Jugoslav

Jugoslav www.xeffort.com

> Steve, I'm not familiar with PC assembly, but I'd
> expect that zero/non-zero test takes one instruction,
> but LSB test takes two. Am I right?

Yes. We had some conflicting goals with CVF, in that we wanted to be compatible with PowerStation but also with our existing Fortran compilers and applications written for them. CVF supports the zero-nonzero definition of LOGICAL if you specify /fpscomp:logicals - but I have a hard time believing you could notice the performance difference in a typical application.

Six years later, there are some decisions we wish we had made differently, but, as they say, hindsight is 20/20. (Meaning, if you're not familiar with the term, that you can see the past with perfect vision.) Some of these decisions will be "revisited" for Intel Visual Fortran, the most notable of which is the default of the STDCALL convention, which has, overall, been more trouble than benefit.

Steve

Steve

Personally, I've never had problems with stdcall. It has the slight advantage over cdecl that you cannot mismatch number of arguments in "f77" style of programming (no explicit interface). I have a bad feeling that many of mixed-language projects where !DEC$ATTRIBUTES STDCALL wasn't specified will break with the new IVF. Well, the price must be paid somewhere... At least, you should include "default calling convention" compiler switch as in VC++ (I guess it is in IFC7 already - /Gm?).

Jugoslav

Jugoslav www.xeffort.com

There will be appropriate switches to establish different combinations for default calling conventions.

Steve

Steve

We sure miss that VAX calling standard... Anyhow I think the right decision was made with CVF, even in retrospect.

James

Well, you haven't had to deal with the zillions of customers who complain that their code, which works "everywhere else" (read "Unix"), doesn't build with CVF because of deliberate argument mismatches....

Steve

Steve

Ahhh... I see now ;-). IIRC the very possibility of mismatch was mentioned in small print somewhere deep in Kernighan&Ritchie, and nowhere in Fortran books that I recall, but apparently when after someone had discovered it was possible it spread like a plague :-(. Oh well.

Jugoslav

Jugoslav www.xeffort.com

>
> -1 is used as it is ".NOT. 0"
>

Ah, that's reasonable but I guess you had to be there.

Ciao,
Gerry T.

Login to leave a comment.