Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Logical Expression Oddity.

llynisa
Beginner
763 Views
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
0 Kudos
15 Replies
Jugoslav_Dujic
Valued Contributor II
763 Views
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
0 Kudos
llynisa
Beginner
763 Views
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
0 Kudos
Jugoslav_Dujic
Valued Contributor II
763 Views
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
0 Kudos
gfthomas8
Novice
763 Views
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.
0 Kudos
Jugoslav_Dujic
Valued Contributor II
763 Views
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
0 Kudos
gfthomas8
Novice
763 Views
> 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

0 Kudos
Steven_L_Intel1
Employee
763 Views
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
0 Kudos
Jugoslav_Dujic
Valued Contributor II
763 Views
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
0 Kudos
gfthomas8
Novice
763 Views
>
> -1 is used as it is ".NOT. 0"
>

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

Ciao,
Gerry T.
0 Kudos
Steven_L_Intel1
Employee
763 Views
> 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
0 Kudos
Jugoslav_Dujic
Valued Contributor II
763 Views
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
0 Kudos
Steven_L_Intel1
Employee
763 Views
There will be appropriate switches to establish different combinations for default calling conventions.

Steve
0 Kudos
james1
Beginner
763 Views
We sure miss that VAX calling standard... Anyhow I think the right decision was made with CVF, even in retrospect.

James
0 Kudos
Steven_L_Intel1
Employee
763 Views
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
0 Kudos
Jugoslav_Dujic
Valued Contributor II
763 Views
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
0 Kudos
Reply