.FALSE. and .TRUE. are not recognized

.FALSE. and .TRUE. are not recognized

===== FALSE. and .TRUE. are not recognized ======

1. Source Code ------------------

Following code is a part of a Fortran file generated from a special text file by a "Translator" - C++ application.

IF (.NOT.(e5LY113.FSELIN.VAL.EQ.-1.AND.eG1132FL1.PVFL.VAL.EQ..FALS
*E..AND.lPREFL.VAL.EQ..FALSE.)) THEN
.......
END IF

2. Problem ----------------------

When set e5LY113.FSELIN.VAL = -1, eG1132FL1.PVFL.VAL = 0, and lPREFL.VAL = 0 from watch window of VC++, final condition should be false and condition block should be bypassed. However, it is treated as true.
If separate it into 3 single condition, results are correct. If combine any 2 of 3 condition or 3 togather like above sample, results are wrong.

3. Walkaround ----------------------

If change code to:

IF (.NOT.(e5LY113.FSELIN.VAL.EQ.-1.AND..NOT.(eG1132FL1.PVFL.VAL).AND..NOT.(lPREFL.VAL)) THEN
.......
END IF

or:

IF (.NOT.(e5LY113.FSELIN.VAL.EQ.-1.AND.eG1132FL1.PVFL.VAL.EQ.0.AND.lPREFL.VAL.EQ.0)) THEN
.......
END IF

Results are ok.

4. Addition info --------------------

i. Values of above variables are fetched by C/C++ functions.

ii. Other code to check .TRUE. has similar problem.

5. Question -------------------

i. What is cause of this problem? different size of data type between C and Fortran?

ii. How to avoid it without changing condition statement syntax? If change syntax, it may affect many other files and worsen readability.

iii. What precaution should I take when pass value between Fortran and C?

iv. How can I quickly find memory address of a variable of Fortran file in VC++ debugger?

====================== End ======================

JQ

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

i, ii, iii) The cause is different treatment of logical variables in two languages. In CVF, literal constant .TRUE. has value -1 = 0xFFFFFFFF and .FALSE. has value 0. However, a variable is considered true when its LSB is set, i.e. if (nVar&1 != 0). Unfortunately, CVF by default allows liberal mixing of LOGICALs and INTEGERs, consequence of which you see.

Equity of two logicals should not be tested using .EQ. but .EQV. operator. So, the original code is non-standard; I can't tell why it failed but I'd suggest fixing it -- and switch on "F95 Standard Warnings" in Project Settings.

iv) If the variable is accessible in the debugger, you can type LOC(variable) in Watch/QuickWatch window, or variable name in Memory window.

Jugoslav
www.xeffort.com

================= Q2: Further tips are needed ======================

Replace EQ with EQV for logic comparison does not fix the problem. Further testing shows results are affected by other execution routes or code before the checked one.

Source code:

1
if (.not.(e5LY113.FSELIN.VAL.EQ.-1)) then
AREG(LOCAL_STMT) = 34.0
end if
if (.not.(eG1132FL1.PVFL.VAL.EQ..FALS
*E.)) then
AREG(LOCAL_STMT) = 34.0
end if
if (.not.(lPREFL.VAL.EQ..FALSE.)) then
AREG(LOCAL_STMT) = 34.0
end if

2
if(.NOT.(e5LY113.FSELIN.VAL.EQ.-1.AND.eG1132FL1.PVFL.VAL.EQ..FALS
*E.)) then
AREG(LOCAL_STMT) = 34.0
end if

3
if(.not.(eG1132FL1.PVFL.VAL.EQ..FALS
*E..AND.lPREFL.VAL.EQV..FALSE.)) then
AREG(LOCAL_STMT) = 34.0
end if

4
if(.not.(eG1132FL1.PVFL.VAL.EQ..FALS
*E..AND.lPREFL.VAL.EQ..FALSE.)) then
AREG(LOCAL_STMT) = 34.0
end if

5
IF (.NOT.(e5LY113.FSELIN.VAL.EQ.-1.AND.eG1132FL1.PVFL.VAL.EQ..FALS
*E..AND.lPREFL.VAL.EQ..FALSE.)) THEN
AREG(LOCAL_STMT) = 34.0
END IF

6
IF (.NOT.(e5LY113.FSELIN.VAL.EQ.-1.AND.eG1132FL1.PVFL.VAL.EQ.0
*.AND.lPREFL.VAL.EQ.0)) THEN
AREG(LOCAL_STMT) = 34.0
END IF

7
IF (.NOT.(e5LY113.FSELIN.VAL.EQ.-1.AND.eG1132FL1.PVFL.VAL.EQ..FALS
*E..AND.lPREFL.VAL.EQ..FALSE.)) THEN
AREG(LOCAL_STMT) = 32.0
AREG(LOCAL_STMT) = 34.0
GOTO START_LABEL
END IF
------------------------------------------------------------------------------------------------------------------------------------------------
7 is original code. The others are testing code.
Execute sequence
i. 1 > 7: 2, 4, 5 are wrong, the others are correct.
ii. 7 only 7 is wrong
iii. if execute 6 before 7, 7 is correct. In all other cases of missing 6, 7 are always incorrect.
iv. 3 and 4 are exactly the same code. 3 seems always right and 4 is wrong.

JQ

Perhaps a ready to compile example would help. The code itself doesn't indicate a particular problem (although I would tend to simply use numeric values rather than logical constants here, but...). This would show the structure variable definitions which might be helpful in understanding the problem.

James

==== Can~{!/~}t integer be compared with logic? ===

After further testing, the problem seems from comparison between different data type.

Original code:
IF (.NOT.(e5LY113.FSELIN.VAL.EQ.-1.AND.eG1132FL1.PVFL.VAL.EQ..FALS
*E..AND.lPREFL.VAL.EQ..FALSE.)) THEN
~{!-!-!-!-!-!-!-!-!-!-~}
END IF

I guess eG1132FL1.PVFL.VAL and lPREFL.VAL are integers (the variables are passed from other files which I can~{!/~}t access), because values of them in watch window are ~{!0~}0~{!1~}, logic variable is supposed to have value ~{!0~}.FALSE.~{!1~}. Although their hex values are exactly the same, Fortran seems not to compare them with logic constant TRUE and FALSE.

There are three solutions:
1. To use logic intermediate variables to transfer integer value

INTEGER iFSELIN
LOGICAL bPVFL
LOGICAL b1PREFL

iFSELIN = e5LY113.FSELIN.VAL
bPVFL = eG1132FL1.PVFL.VAL
b1PREFL = lPREFL.VAL

IF (.NOT.(iFSELIN.EQ.-1.AND.bPVFL.EQ..FALS
*E..AND.b1PREFL.EQ..FALSE.)) THEN
~{!-!-!-!-!-!-!-!-!-~}
END IF

2. To compare integer only

IF (.NOT.(e5LY113.FSELIN.VAL.EQ.-1.AND.eG1132FL1.PVFL.VAL.EQ.0
*.AND.lPREFL.VAL.EQ.0)) THEN
~{!-!-!-!-!-!-~}..
END IF

3. To workaround

If value is

IF (.NOT.(e5LY113.FSELIN.VAL.EQ.-1.AND..NOT.(eG1132FL1.PVFL.VAL)
*.AND..NOT.(lPREFL.VAL)) THEN
~{!-!-!-!-~}.
END IF

What I will do is not directly change Fortran code. I have to modify ~{!0~}Translator~{!1~} to generate one of above pattern. According to reply of jugoslavdujic and james, solution 2 seems more reliable, safety and easier to implement. Any other suggestion?

JQ

You may want to see if compiling the code with the /fpscomp:logicals option (Settings..Fortran..Compatibility..PowerStation..Logicals) helps - this will change the representation of .TRUE. and .FALSE. to 1 and 0. As noted earlier, however, your code is broken in that it assumes particular integer values for LOGICALs.

Steve

Retired 12/31/2016

Leave a Comment

Please sign in to add a comment. Not a member? Join today