Evaluate Expression .AND. error

Evaluate Expression .AND. error

Hi,

I have a expression like this:

I = 5

DO WHILE (I <= 4 .AND. "ThrowError")
            'Do something'
            I = I + 1
ENDDO

In Intel Fortran, as the variable I is greather than 4, the second part of the .AND. operator shouldnt even be evaluated, correct? (since the first operand is .FALSE.) But thats not the case, the second part is evaluated and throws an error. 

In compaq fortran that expression works as expect: the execution verifies that the first operand is .FALSE. and dont continue evaluating the expression.

Does anyone know anything about it?

 

15 posts / novo 0
Último post
Para obter mais informações sobre otimizações de compiladores, consulte Aviso sobre otimizações.

The compiler can evaluate in any order it chooses and may evaluate some or all terms. If you want standard fortran you cannot assume the order...

Both terms will be evaluated.

The .and. behaves like the & operator in C. There isn´t an operator like && in Fortran.

I don´t like it too because for array checks you always have to use two if clauses

! this one will crash when i <= 0
if(i > 0 .and. array(i) < 5) then
! do something
end if
! this one works
if(i>0) then
    if(array(i) < 5) then
! do something
end if

Because if i is 0 array(0) is out of bounds...

 

Markus

From the Intel Fortran documentation:

You should not write logical expressions whose results might depend on the evaluation order of subexpressions. The compiler is free to evaluate subexpressions in any order.

and

Logical operations cannot be performed on other data types (than logical or integer).

Your understanding is incorrect regarding whether short-circuit evaluation is required.

Secondly, I do not understand what you expect to happen when a character constant is used in a place where a logical (or, grudgingly, an integer expression) is expected; perhaps you used "ThrowError" as a place-holder for something longer that is of type logical.

Although one can make arguments for and against short-circuited evaluation of logical/boolean expressions, one needs to remember that a Fortran program that depends on order of evaluation or enforced short-circuiting is not a standard-conforming program.

see also http://software.intel.com/en-us/forums/topic/293083. Some ancient Fortran compilers indeed evaluated "if" clauses from left to right, stopping the evaluation if a term was false. I don't know if that was just a convention or an ommission in the Fortran standard. Now the standard says clearly that the clauses are not neccessarily evaluated from left to right. You have no other possibility than to check your sources and correct the dubious if clauses.

Would there be any support for extending the language to handle this type of situation by adding ordered versions of .and. and .or., for example .oand. and .oor. or .andif. and .orif. ?  Is it difficult for the compiler writers?

Citação:

rase escreveu:

...Some ancient Fortran compilers indeed evaluated "if" clauses from left to right, stopping the evaluation if a term was false.

Those ancient compilers, as well as current standard-conforming compilers, are allowed to do so. The programmer who assumes that they will always do so, however, does so at his/her own peril. I see this issue as not much different from, say, assuming that variables are by default initialized to zero, blank, .true., etc., just because some widely-used older compiler did so in the past.

That said, it is a business decision for the compiler vendor as to whether an option should be provided to allow non-standard-conforming codes to continue to run "correctly".

>>Is it difficult for the compiler writers?

It is not a case of being difficult to do. Rather, it is a case of following the rules of the language.

The language states any order including concurrently

Assume:

IF(functionA(arg) .OR. functionB(arg)) CALL something()

If functionA and functionB maintain global states, Then shortcutting the above IF statement may cause state inconsistency.
IOW break working code.

Jim Dempsey

www.quickthreadprogramming.com

f2c is the only Fortran translator I know of which followed C style shortcut evaluation. I would have expected it to reject violations of Fortran 77 such as using .and. with a character string. Any compiler which did permit this would be too untrustworthy for any possibility of a maintained compiler to emulate. If CVF accepted this on the grounds of evaluation to .false. you might as well comment out the bad part.

Couldn't you just write what you want explicitly?  E.g.

I = 5

DO WHILE (I <= 4)

            IF( .NOT. "ThrowError") EXIT
            'Do something'
            I = I + 1
ENDDO

 I'm assuming the stuff in quotes is just shorthand for a legal expression of some sort.

Whilst I understand the inconvenience of having to fix old codes, it's not realistic to introduce new, non-standard language features every time something like this crops up, the list would be overwhelming. Of course, if you could convince the standards committee, which includes our own Steve Lionel, that would be another matter...

Citação:

It is not a case of being difficult to do. Rather, it is a case of following the rules of the language.

The language states any order including concurrently

Assume:

IF(functionA(arg) .OR. functionB(arg)) CALL something()

If functionA and functionB maintain global states, Then shortcutting the above IF statement may cause state inconsistency.
IOW break working code.

The point of adding new operators as I suggested would be to avoid breaking existing code. I doubt very much that the language rules say anything about operators that don't yet exist.

 

I am not sure what your motivation to having C-style logical operator evaluation (left to right, stop evaluation upon first satisfaction).

Other than "it looks like C" you might have the misconception that it will generate faster code.

Consider

IF((A .GT. B) .OR. (C.LT.D)) E = F

In the above case, with processor having conditional move, there are no branches required if you do both evaluations.

And yes there are counter examples, such as your original one where I assume "ThrowError" is an expression that would generate an error that you would rather not encounter, e.g. divide by zero.

The problem you are wishing to resolve is a change in language. This is hard to do without breaking existing code. Martyn gave you a good example of how to Fortran-ize your C-style thinking.

How about using FORTH or LISP style expression evaluations and IF statements?

Jim Dempsey

 

www.quickthreadprogramming.com

Jim Dempsey wrote: 

The problem you are wishing to resolve is a change in language. This is hard to do without breaking existing code.

There are more objections to the addition of operators and language features without going through the language standards body.

The compiler people have to ensure that the additions do not cause changes in the behavior of programs that do not use the extensions.

The primary users of the new operators have to contend with the problem that their code is now going to create for secondary users whose compilers either do not support the new operators or do so with a slightly different implementation.

Deixar um comentário

Faça login para adicionar um comentário. Não é membro? Inscreva-se hoje mesmo!