- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Message Edited by WKRAMER on 10-19-2005 02:06 PM
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This question is related to another current thread in this forum:
http://softwareforums.intel.com/ids/board/message?board.id=5&message.id=15406
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I would be careful about passing LOGICAL in Fortran to a windows routine that expects a bool. The reason being that the internal representation of what is .true. or .false. is left up to the implimentators of the FORTRAN compiler as well as to the C++ compiler. You are not guaranteed that the internal storage format is the same between F90 and C++ less alone between F90 vendor A and F90 vendor B or F90 V9.0.024 vendor A and F90 V10.0.1 vendor A.
Common values are 0, 1, -1, .ne. 0, .lt. 0, .gt. 0 and the interpritation of what is true or false is up to the implimentation.
You will often find that "(x .eq. .true.)" and "(.not. (x .eq. .false.))" don't agree with each other when going mixed language.
Words of caution.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I would suggest thattwo C++ subroutines that are callable from FORTRAN, one that returns the boolian true and one that returns the boolian false. If C++ calls FORTRAN then create two FORTRAN routines callable from C++, one that returns .true. as integer(4)and one that returns .false. as integer(4). Take care in the issue of wether you pass by value or by reference. You may also want to create a FORTRAN function, callable from FORTRAN that has for input a LOGICAL and which returns the appropriateC++ boolian. With these little wrapper frunctions your code will be portable and it won't break should something change in the future.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
An attention should be paid though that CVF (and probably IVF as well) checks only the LSB of a logical expression to evaluate it. Thus, e.g. 0x00000002 has value .FALSE. in VF. However, I've never seen an API documented to return a BOOL returning anything other than 0x00000000 and 0x00000001.
So, my conclusion is that integer(BOOL) should be used in new codes but "old style" codes (using logical) don't have to be fixed (if the compiler does not complain, of course.)
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
if (aLogical) then !is fineI'm not sure if the last expression is allowed in standard F95, or it's just a FPS/CVF extension?
if (aLogical .eqv. .true.) then !is fine as well (is it?)
if (aLogical .eq. .true.) then !is NOT fine
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
CVF program with /stand:f95:
program BoolTestJugoslav
logical:: b1 = .true., b2 = .true., b3 = .true.
if (b1.eq.b2) b3 = .false.
end program BoolTest
...
BoolTest.f90(5) : Warning: Fortran 95 does not allow a LOGICAL
data type in this context. [B1]
BoolTest.f90(5) : Warning: Fortran 95 does not allow a LOGICAL
data type in this context. [B2]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Someone needs to work on the Reply to Message system. As you can see by the multiple posts. This occured because when I wanted to indent some text I pressed the Tab key and the focus went to the Submit Message button. Then when I noticed the indentating did not occure I pressed the spacebar several times toindent the text (focus still on Submit Message)... this poped in several copies of the unfinished message.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What I wanted to say is illustrated by the Dissassembly Window snippette below
logical fooEQV, a, b
fooEQV = (a .eqv. b)
0040110F 8B 00 mov eax,dword ptr [eax]
00401111 33 02 xor eax,dword ptr [edx]
00401113 F7 D0 not eax
end function fooEQV
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- VF evaluates (a.eqv.b) as NOT(IEOR(a,b)) (bitwise)
- the bit-pattern of the result is correct according to VF logical semantics, i.e. LSB is correctly set or cleared.
- however, the resulting bit-pattern need not conform to C semantics, i.e. it can happen that a VF .FALSE. evaluates to C TRUE, i.e. a value different than 0.
If so, point taken. Thanks for the exercise.
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Doctor Fortran in "To .EQV. or to .NEQV., that is the question", or "It's only LOGICAL"
By Steve Lionel
Visual Fortran Engineering
Most Fortran programmers are familiar with the LOGICAL data type, or at least they think they are.... An object of type LOGICAL has one of only two values, true or false. The language also defines two LOGICAL constant literals .TRUE. and .FALSE., which have the values true and false, respectively. It seems so simple, doesn't it? Yes... and no.
The trouble begins when you start wondering about just what the binary representation of a LOGICAL value is. An object of type "default LOGICAL kind" has the same size as a "default INTEGER kind", which in Visual Fortran (and most current Fortran implementations) is 32 bits. Since true/false could be encoded in just one bit, what do the other 31 do? Which bit pattern(s) represent true, and which represent false? And what bit patterns do .TRUE. and .FALSE. have? On all of these questions, the Fortran standard is silent. Indeed, according to the standard, you shouldn't be able to tell! How is this?
According to the standard, LOGICAL is its own distinct data type unrelated to and not interchangeable with INTEGER. There is a restricted set of operators available for the LOGICAL type which are not defined for any other type: .AND., .OR., .NOT., .EQV. and .NEQV.. Furthermore, there is no implicit conversion defined between LOGICAL and any other type.
"But wait," you cry! "I use .AND. and .OR. on integers all the time!" And so you do - but doing so is non-standard, though it's an almost universal extension in today's compilers, generally implemented as a "bitwise" operation on each bit of the value, and generally harmless. What you really should be using instead is the intrinsics designed for this purpose: IAND, IOR and IEOR.
Not so harmless is another common extension of allowing implicit conversion between LOGICAL and numeric types. This is where you can start getting into trouble due to implementation dependencies on the binary representation of LOGICAL values. For example, if you have:
INTEGER I,J,K
I = J
just what is the value of I? The answer is "it depends", and the result may even vary within a single implementation. Compaq Fortran traditionally (since the 1970s, at least) considers LOGICAL values with the least significant bit (LSB) one to be true, and values with the LSB zero to be false. All the other bits are ignored when testing for true/false. Many other Fortran compilers adopt the C definition of zero being false and non-zero being true. (Visual Fortran offers the /fpscomp:logicals switch to select the C method, since PowerStation used it as well.) Either way, the result of the expression J
The real trouble with making assumptions about the internal value of LOGICALs is when you try testing them for "equality" against another logical expression. The way many Fortran programmers would naturally do this is as follows:
IF (LOGVAL1 .EQ. LOGVAL2) ...
but the results of this can vary depending on the internal representation. The Fortran language defines two operators exclusively for use on logical values, .EQV. ("equivalent to") and .NEQV. ("not equivalent to"). So the above test would be properly written as:
IF (LOGVAL1 .EQV. LOGVAL2) ...
In the Doctor's experience, not too many Fortran programmers use .EQV. and .NEQV. where they should, and get into trouble when porting software to other environments. Get in the habit of using the correct operators on LOGICAL values, and you'll avoid being snared by implementation differences.
However, there is one aspect of these operators you need to be aware of... A customer recently sent us a program that contained the following statement:
DO WHILE (K .LE. 2 .AND. FOUND .EQV. .FALSE.)
The complaint was that the compiler "generated bad code." What the programmer didn't realize was that the operators .EQV. and .NEQV. have lower precedence than any of the other predefined logical operators. This meant that the statement was treated as if it had been:
DO WHILE (((K .LE. 2) .AND. FOUND) .EQV. .FALSE.)
what was wanted instead was:
DO WHILE ((K .LE. 2) .AND. (.FOUND .EQV. .FALSE.))
The Doctor's prescription here is to always use parentheses! That way you'll be sure that the compiler interprets the expression the way you meant it to! (And you therefore don't have to learn the operator precedence table you can find in chapter 4 of the Compaq Fortran Language Reference Manual!)
Message Edited by sblionel on 10-21-2005 08:35 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Doctor Fortran in "To .EQV. or to .NEQV., that is the question", or "It's only LOGICAL"
By Steve Lionel
Visual Fortran Engineering
Most Fortran programmers are familiar with the LOGICAL data type, or at least they think they are.... An object of type LOGICAL has one of only two values, true or false. The language also defines two LOGICAL constant literals .TRUE. and .FALSE., which have the values true and false, respectively. It seems so simple, doesn't it? Yes... and no.
The trouble begins when you start wondering about just what the binary representation of a LOGICAL value is. An object of type "default LOGICAL kind" has the same size as a "default INTEGER kind", which in Visual Fortran (and most current Fortran implementations) is 32 bits. Since true/false could be encoded in just one bit, what do the other 31 do? Which bit pattern(s) represent true, and which represent false? And what bit patterns do .TRUE. and .FALSE. have? On all of these questions, the Fortran standard is silent. Indeed, according to the standard, you shouldn't be able to tell! How is this?
According to the standard, LOGICAL is its own distinct data type unrelated to and not interchangeable with INTEGER. There is a restricted set of operators available for the LOGICAL type which are not defined for any other type: .AND., .OR., .NOT., .EQV. and .NEQV.. Furthermore, there is no implicit conversion defined between LOGICAL and any other type.
"But wait," you cry! "I use .AND. and .OR. on integers all the time!" And so you do - but doing so is non-standard, though it's an almost universal extension in today's compilers, generally implemented as a "bitwise" operation on each bit of the value, and generally harmless. What you really should be using instead is the intrinsics designed for this purpose: IAND, IOR and IEOR.
Not so harmless is another common extension of allowing implicit conversion between LOGICAL and numeric types. This is where you can start getting into trouble due to implementation dependencies on the binary representation of LOGICAL values. For example, if you have:
INTEGER I,J,K
I = J
just what is the value of I? The answer is "it depends", and the result may even vary within a single implementation. Compaq Fortran traditionally (since the 1970s, at least) considers LOGICAL values with the least significant bit (LSB) one to be true, and values with the LSB zero to be false. All the other bits are ignored when testing for true/false. Many other Fortran compilers adopt the C definition of zero being false and non-zero being true. (Visual Fortran offers the /fpscomp:logicals switch to select the C method, since PowerStation used it as well.) Either way, the result of the expression J
The real trouble with making assumptions about the internal value of LOGICALs is when you try testing them for "equality" against another logical expression. The way many Fortran programmers would naturally do this is as follows:
IF (LOGVAL1 .EQ. LOGVAL2) ...
but the results of this can vary d epending on the internal representation. The Fortran language defines two operators exclusively for use on logical values, .EQV. ("equivalent to") and .NEQV. ("not equivalent to"). So the above test would be properly written as:
IF (LOGVAL1 .EQV. LOGVAL2) ...
In the Doctor's experience, not too many Fortran programmers use .EQV. and .NEQV. where they should, and get into trouble when porting software to other environments. Get in the habit of using the correct operators on LOGICAL values, and you'll avoid being snared by implementation differences.
However, there is one aspect of these operators you need to be aware of... A customer recently sent us a program that contained the following statement:
DO WHILE (K .LE. 2 .AND. FOUND .EQV. .FALSE.)
The complaint was that the compiler "generated bad code." What the programmer didn't realize was that the operators .EQV. and .NEQV. have lower precedence than any of the other predefined logical operators. This meant that the statement was treated as if it had been:
DO WHILE (((K .LE. 2) .AND. FOUND) .EQV. .FALSE.)
what was wanted instead was:
DO WHILE ((K .LE. 2) .AND. (.FOUND .EQV. .FALSE.))
The Doctor's prescription here is to always use parentheses! That way you'll be sure that the compiler interprets the expression the way you meant it to! (And you therefore don't have to learn the operator precedence table you can find in chapter 4 of the Compaq Fortran Language Reference Manual!)
Message Edited by sblionel on 10-21-2005 08:41 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Applause, applause...
Re: DO WHILE (((K .LE. 2) .AND. FOUND) .EQV. .FALSE.)
what was wanted instead was:
DO WHILE ((K .LE. 2) .AND. (.FOUND .EQV. .FALSE.))
With context sensitive editors and intelisensewouldn't it be nice to have the precidence depenent portions highlighted in some manner? Example: assume mouse pointer over .AND.
(K .LE. 2 .AND. FOUND .EQV. .FALSE.)
Even when used with the parens complex expressions might benifit from highlighting.
Jim
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page