Silverfrost Forums

Welcome to our forums

Embedded blanks in operators

19 Jan 2011 8:28 #7543

Is it correct that in Fortran 9x free source form, an operator may not contain embedded blanks? The following code gives an example where FTN95 accepts such blanks:

winapp
  
program prog1
  implicit none
  Real :: a,b
  a = 1.
  b = 2.

! How must relational operators be written?

  if ( b .gt.      a ) write (*,*) 'a, b = ', a, b ! correct
  if ( b .     gt. a ) write (*,*) 'a, b = ', a, b ! correct?
  if ( b .gt     . a ) write (*,*) 'a, b = ', a, b
  if ( a . gt. 0.1  . and . b .gt  . 0.1) write (*,*) 'a, b = ', a, b
end program prog1

I am not sure whether for instance “.GT.” should be considered as one “token” or whether the token is only “GT”. What exactly does the standard say?

From a previous thread I learned that such details may be considered as pedantic (ASparge). They are NOT. Just imagine that a large system of programs is released to customers who use different compilers. This is our situation. We have always recommended to our customers FTN77, later FTN95 but of course a user is completely free to use a compiler of his choice. Nevertheless, up to now, where we released the code in fixed source form, we have never heard of any portability problems. Many thanks to Salford and Silverfrost! However, this is not the case with FTN95 and the free source form. I am right now analyzing further problems.

A last remark: We all know about the situation of Fortran. The fastest way to ring the bells for Fortran 9x would be the development of compiler dialects including “specific” implementations. No manager would support the investment of –say- 20 or even more man-years into the development of a Fortran program if it cannot guaranteed that every user could use it. Only very minor adaptions would be acceptable.

  1. Lassmann
19 Jan 2011 10:13 #7544

Klaus,

as far as I know, it is recommended to use '>' instead of '.gt.' and so on in Fortran95 code, and it seems to be the actual standard now. I found a short text with some advise for the portability of Fortran code: click

Hope that this can help a little.

Regards - Wilfried

19 Jan 2011 2:20 #7548

Wilfried,

I've been a believer in compiling with as many compilers as I can get my hands on, but this is a huge luxury only available in a few environments such as the PC. For most of history, you were stuck with the compiler that came with your hardware, and to even get the code to work elsewhere you may have needed to translate even the punched cards, and use system-specific commands.

I had a look at your reference: it rules out all legacy code, obviously. Also rules out Clearwin+. Makes it pretty difficult to use many forms of graphics, and most non-trivial user interfaces. Fair enough, for some programs, portability is mission-critical. For others, the user-interface is all. In the latter case, there isn't much choice but to contravene most of the rules in that guide! (For me, the choice is FTN95 or give up).

Most of the fixes reported in any compiler's history of bug fixes (e.g. FTN95, but it isn't alone) relate to 90/95/2003 features - and therefore by definition, the newer language features cannot form part of a 'Safer Subset' (viz. the writings of Les Hatton).

It has never been clear to me how KIND was more reliable than 'typen' e.g. REAL8 (in the real world, and no pun on the word real intended).

Eddie

19 Jan 2011 2:34 #7550

Wilfried,

thanks for the information. I had already considered such a possibility, but I have never seen such a form as the only standard form. It also seems to me that your reference is more a recommendation (...it is encouraged to use...) rather than a rule.

Klaus

19 Jan 2011 3:34 #7555

I have looked at the standard and it seems that this is not clearly defined.

The compiler preprocesses fixed format code by removing spaces except in string quotes. This is effectively Fortran 77 so spaces are accepted within intrinsic operators.

In free format code spaces become significant and the standard intrinsics are defined in the Fortran standard without embedded spaces. Also user-defined operators must only contain letters.

I guess it was a reasonable assumption for FTN95 to not allow spaces in free format intrinsic operators but other compilers may be more flexible at this point.

I don't know off hand how much work would be involved in allowing this as a sort of extension.

19 Jan 2011 5:39 #7559

Paul, may be that I misunderstand you. In my opinion it is just the opposite: FTN95 accepts blanks in expressions like . eq. (please see my example code), which in my opinion it should better not.

Klaus

19 Jan 2011 7:16 #7560

OK I see the difference. Your examples have leading or trailing spaces. I was putting spaces between the letters.

So in fixed format code you can have spaces anywhere between the dots whilst in free format code you can only have leading or trailing spaces between the dots.

As before, I guess that this could be changed except that there might just be someone out there whose code I would break by making the change.

20 Jan 2011 10:59 #7571

Paul,

I have no idea what the standard exactly says. I understood from all what I have read, that an operator or separator such as '(/' or '/)' or name or number may not contain embedded blanks. In my opinion it is therefore not consistent to allow embedded trailing blanks after the dot or leading blanks before the dot in an operator like '.and.' This should lead to an error message or at least to a warning.

For our application I have written a conversion program that removes such blanks, because they lead to error messages in other compilers.

Best regards,

Klaus

20 Jan 2011 2:16 #7577

The standard (ISO/IEC 1539-1 2010) says:

3.3.2.2 Blank characters in free form 1 In free source form blank characters shall not appear within lexical tokens other than in a character context or in a format specification. Blanks may be inserted freely between tokens to improve readability; for example, blanks may occur between the tokens that form a complex literal constant. A sequence of blank characters outside of a character context is equivalent to a single blank character.

2 A blank shall be used to separate names, constants, or labels from adjacent keywords, names, constants, or labels.

For example, the blanks after REAL, READ, 30, and DO are required in the following: REAL X READ 10 30 DO K=1,3

3 One or more blanks shall be used to separate adjacent keywords except in the following cases, where blanks are optional: Adjacent keywords where separating blanks are optional BLOCK DATA END INTERFACE DOUBLE PRECISION END MODULE ELSE IF END PROCEDURE ELSE WHERE END PROGRAM END ASSOCIATE END SELECT END BLOCK END SUBMODULE END BLOCK DATA END SUBROUTINE END CRITICAL END TYPE END DO END WHERE

Regards Ian

20 Jan 2011 4:51 #7588

I suppose it all boils down to whether .AND. is a single 'lexical token' or 3 ('.' , 'AND' and '.'). I would have put my money on it being just one.

Apart from embedded blanks not working with other compilers, what potential problems could occur by permitting the embedded blanks in this context, e.g. treating .AND. as 3 lexical tokens? Of course, if it is (they are) 3, then blanks are surely compulsory in free format!

I always hated these so-called logical operators. Bring back the Arithmetic IF !!! 😉

Eddie

21 Jan 2011 9:03 #7592

Can this not be answered by seeing what the definition of a 'Token' is. If a token is not allowed to be '.' then it would follow that '.gt.' cannot be three tokens.

Personally I prefer >, >= etc (but why do we have to suffer the dreadful /= when != would have been more natural.)

Quoted from LitusSaxonicum

I always hated these so-called logical operators. Bring back the Arithmetic IF !!! 😉

But you still need them even with the Arithmetic if. 😛

21 Jan 2011 9:03 #7593

Can this not be answered by seeing what the definition of a 'Token' is. If a token is not allowed to be '.' then it would follow that '.gt.' cannot be three tokens.

Personally I prefer >, >= etc (but why do we have to suffer the dreadful /= when != would have been more natural.)

Quoted from LitusSaxonicum

I always hated these so-called logical operators. Bring back the Arithmetic IF !!! 😉

But you still need them even with the Arithmetic if. 😛

21 Jan 2011 9:04 #7594

Can this not be answered by seeing what the definition of a 'Token' is. If a token is not allowed to be '.' then it would follow that '.gt.' cannot be three tokens.

Personally I prefer >, >= etc (but why do we have to suffer the dreadful /= when != would have been more natural.)

Quoted from LitusSaxonicum

I always hated these so-called logical operators. Bring back the Arithmetic IF !!! 😉

But you still need them even with the Arithmetic if. 😛

21 Jan 2011 9:05 #7595

Oops, there is some issue with posting I see. Apologies for the multiple post.

24 Jan 2011 12:00 #7614

Paul,

the discussion shows that this issue needs to be clarified. Metcalf defines a token as a sequence of alphanumeric or special characters and refers to a table which defines the tokens “.eq.”, “.ne.” etc. For me this indicates that the dot in these expressions is part of the token and is not be considered as separator or something else.

The free format of FTN95 not only allows having trailing blanks after the dot at the begin and leading blanks before the dot at the end for operational operators, but also for logical operators and for .true. and .false. as well. FTN95 does not give an error message for a statement such as

If ( (. not . x) . and . y ) z = . true .

Of course this is extremely bad programming. Further the colorization in most editors would not mark anything in this line.

Nevertheless, if –as you say- this is not clearly defined by the standard, I would suggest to make this an issue for the standard committee. We do not increase the portability of free format Fortran 9x if such simple definitions stay unclear.

Klaus

24 Jan 2011 12:04 #7615

I should have better put my example as

If ( (.  not  . x) .   and          . y ) z = . true   .
24 Jan 2011 10:07 #7617

Davidb:

Do you really (need logical operators) if all you have is an arithmetic IF (e.g. as in IBM1130 Fortran), or do they simply make the code more readable?

I'm still using this line, programmed in 1969 (I think) on said machine:

      IF ((H+0.40D0)*(H-0.50D0)) 7,7,4

because I can't puzzle out what the heck it does! (But I'm sure it has an .AND. in it).

Klaus:

FTN95 doesn't like the parts of a compound operator specified F90 style (e.g. ⇐) to be separated. If you don't like fixed format, how can you bear to use those horrid 'dot' operators? Trouble is, the new form isn't much of an improvement, is it?

What is the benefit of adding extra spaces anyway - I find the dotty operators hard enough to read even if the dots are hard up against the letters?

Eddie

25 Jan 2011 11:42 #7618

Klaus,

You wrote 'We do not increase the portability of free format Fortran 9x if such simple definitions stay unclear.' My observation is that portability and the Fortran 9x standard are a bit mixed up. They refused to give guidance on the values of KIND for integer and real. I always thought that the 9x standard tried to introduce portability in OPEN but reading the fine print, 'RECL=' was not standardised.

I think the rule that you should not use spaces within tokens should be applied wherever possible, such as .ne. or variabe_names. That being said, I never use ENDDO or ENDIF. (Ian, what is END CRITICAL ??)

John

25 Jan 2011 12:32 #7619

END CRITICAL - I'm glad you asked me that - It is something to do with multiple images, see below as long as you don't then ask about SYNCH ALL etc. They are part of Fortran 2008. Regards Ian

8.1.5 CRITICAL construct 1 A CRITICAL construct limits execution of a block to one image at a time. R810 critical-construct is critical-stmt block end-critical-stmt R811 critical-stmt is [ critical-construct-name : ] CRITICAL R812 end-critical-stmt is END CRITICAL [ critical-construct-name ] C809 (R810) If the critical-stmt of a critical-construct specifies a critical-construct-name, the corresponding end-critical-stmt shall specify the same critical-construct-name. If the critical-stmt of a critical-construct does not specify a critical-construct-name, the corresponding end-critical-stmt shall not specify a critical- construct-name. C810 (R810) The block of a critical-construct shall not contain a RETURN statement or an image control statement. C811 A branch (8.2) within a CRITICAL construct shall not have a branch target that is outside the construct. 2 Execution of the CRITICAL construct is completed when execution of its block is completed. A procedure invoked, directly or indirectly, from a CRITICAL construct shall not execute an image control statement. 3 The processor shall ensure that once an image has commenced executing block, no other image shall commence executing block until this image has completed executing block. The image shall not execute an image control statement during the execution of block. The sequence of executed statements is therefore a segment (8.5.2). If image T is the next to execute the construct after image M, the segment on image M precedes the segment on image T. NOTE 8.6 If more than one image executes the block of a CRITICAL construct, its execution by one image always either precedes or succeeds its execution by another image. Typically no other statement ordering is needed. Consider the following example: CRITICAL GLOBAL_COUNTER[1] = GLOBAL_COUNTER[1] + 1 END CRITICAL The definition of GLOBAL COUNTER [1] by a particular image will always precede the reference to the same variable by the next image to execute the block. NOTE 8.7 The following example permits a large number of jobs to be shared among the images: INTEGER :: NUM_JOBS[], JOB IF (THIS_IMAGE() == 1) READ(,*) NUM_JOBS SYNC ALL DO CRITICAL JOB = NUM_JOBS[1] NUM_JOBS[1] = JOB - 1 END CRITICAL IF (JOB > 0) THEN ! Work on JOB ELSE EXIT END IF END DO SYNC ALL

25 Jan 2011 5:36 #7621

Thanks for the comments. May be that '>' is better readable than '.gt.' but also this form must be standardised. With the remark about arithmetic IF I do not agree. For very good reasons this construct is on the list of obsolete features. But I do agree -as already said- to write all operators in discussion without any blanks.

To increase portability was -at least as I understood- one of the major goals for the Fortran 90 development. And I think that this goal has been reached to a certain extent. But it is never a mistake to further increase it.

Klaus

Please login to reply.