Silverfrost Forums

Welcome to our forums

Spaces and 72-character limit

7 Feb 2018 6:28 #21328
  1. Can you guys who use Gfortran check its compilation process on how it treats source lines which go beyond 72 character length but have spaces or tabs in the line? I am trying to compile some third-party code made in Gfortran and get hell amount of such situations which FTN95 treats as errors while GFortran either misses errors and allows broken code to run or by ignoring all spaces and tabs allows such longer then 72 character lines to be accepted.

  2. Is

integer(4) :: ier4

double precision integer in Gfortran while and single precision in FTN95 ?

FTN95 give to this 'COMMENT - Specifying the kind of the type INTEGER with a constant is non-portable - 'SELECTED_INT_KIND(18)' would be better'

(Sorry, forum shows number eight as a smilings. How to make it showing eight as a number?)

  1. I get a lot of FTN95 diagnostics

*** Invalid KIND specifier

sometimes without showing the offending line or showing wrong line (this is usual 32bit FTN95 compiler, not 64 one) like this which is due to that time consuming to fix

        NO ERRORS  [<ALLOC_MXRCFG> FTN95 v8.20.0]
*** Invalid KIND specifier
COMMENT - Specifying the kind of the type REAL with a constant is non-portable 
    - 'SELECTED_REAL_KIND(6,37)' would be better
        1 ERROR, 1 COMMENT  [<ALLOC_MXLVLS> FTN95 v8.20.0]

I can send some subroutines to try on request, just PM me

7 Feb 2018 9:34 #21329

I think that gFortran treats tabs as 6 spaces. FTN95 has 8 spaces.

INTEGER(4) is 32 bits in gFortran and 64 bits by default in FTN95 but with FTN95 you can use /alt_kinds on the command line to make it 32 bits.

It looks like it would be a relatively simple job to add a new FTN95 option /TAB 6 etc. in order to change from 8 to 6. Let me know if this would make it significantly easier. However, editors like Plato often have an automatic way to translate tabs into spaces.

7 Feb 2018 9:49 #21330

Dan,

Maybe the compiler option /WIDE_SOURCE will help with longer-than-72 character lines without going to free format. (Obviously no good if there are sequence numbers present!)

Eddie

7 Feb 2018 10:18 #21332

Paul, I see that the author used editor with 8 spaces in Tab. He uses 6th position as a continuation. So looks like the source is standard conforming. Changing spacing to 6 spaces will probably not very convenient for this fixed source code. And the offending lines with more then 72 characters often do not have tabs, only few spaces somewhere between typical 9th position and say 75th. I suspect when Gfortran compiles, it removes these spaces as redundant and the line fits into 72 spaces. Or it has to remove all spaces before actual first letter and place this Fortran word to 7th position instead of 9th, then there will be 2 extra position in the line. Otherwise i have to suppose that their compiler is totally broken by running crazy code with undefined variables, eating without any hiccups expressions with no right parenthesis etc

Eddie, When i will be soon exhausted fixing difficult to find line 72-char limit break-ins (sometimes not in the exact places FTN95 compiler tells. This probably would be a good exercise for Silverfrost to further adjust compiler) i will try your suggestion. Fun is though that this code supposed to run on almost all existing and past Fortran compilers. So i am puzzling now what the heck is going on.

7 Feb 2018 10:44 #21333

Dan,

integer(4) is standard conforming, but not portable. The kind values in gFortran are the same as the byte values (except for complex, which I don't know much about).

I prefer the non-standard typebyte syntax, as it works for both gFortran and FTN95, without any changes. integer(4) becomes integer4, which is recognised by all Fortran 95 compilers that support IEEE 754 numeric formats (ie all current F95 compilers ) There are a number of purists out there that say integer*4 is not standard conforming, but they have not used FTN95 and gFortran together.

What you have to look out for is constants with the kind suffix. 21_4 will default to mean different things in gFortran and FTN95, while /alt_kinds did not always work in this situation. You will have to learn the difference and perhaps use parameters for the different kind values, such as integer, parameter :: int16 = selected_int_kind (4) integer, parameter :: int32 = selected_int_kind (8) integer, parameter :: int64 = selected_int_kind (12)

so integer(4) becomes integer(int32) 21_4 becomes 21_int32

Actually, 21_4 used in FTN95 coding is awful. If you scan the code, you (I) will rarely see the error, as is the case when using 21_3

For some reason Fortran 2008 decided to use kind names, based on bits, rather than bytes. That is the example I have provided. They are not prepared to admit that 8-bit bytes actually exist. They must not use the language and definitely have never used clearwin+

Regarding tabs; remove them !! and go to free format at the same time to remove the 72 character limit.

That should remove a few of the devils. and remember devils hate implicit none !!

Good luck,

John

7 Feb 2018 11:10 #21334

Dan,

A further suggestion is to save the compiler outputs from test compiles with and without \WIDE_SOURCE, then compare them with a file compare utility, which should find the offending lines for you to correct before anything else.

John,

I agree that the KIND business isn't a good solution, as it has not led to any sort of commonality between compilers. Indeed, even the byte-number system doesn't (although it is better) because the split between precision and range is potentially different, although perhaps not by much.

The fundamental defect is that 4 byte reals are almost never good enough, whereas 6-bytes are (8 is better still, but verging on the overkill of 10 or 16). I have a mental rule to determine whether I can use 4, and that is:

'Do all the intermediate results take the form of real physical quantities for which I can identify the dimensions?' (i.e. into units like m, kN, s etc)

If the answer is 'Yes', then typically I could in the past have done the calculations with a slide-rule, and REAL*4 is good enough. When you apply this to (say) finite elements, then what physical units can you apply to the intermediate results when inverting a matrix? The answer is that normal humans (even slightly superhuman engineers) can't, so you need the higher precision.

The exception is angular measurement where I need to resolve 1 second of arc, and 4 byte REALs are never enough. Again, 6 would be fine.

It's easiest to always use 8 bytes, and know that 2 of them are rather useless and wasted most of the time.

Eddie

7 Feb 2018 12:37 #21335

Eddie,

I do find that real8 is adequate, however the only computation where I did use better than real8 has been in the orthogonalisation of eigenvectors in an iterative Eigenvector extraction solution.

      REAL*10 FUNCTION ORTHOG (T1, TMASS, T2, NEQ)
!
!   Computes the tri-vector product where T1,T2 are eigenvectors
!   and TMASS is the diagonal mass matrix
!
      INTEGER*4 NEQ
      real*8    T1(NEQ), TMASS(NEQ), T2(NEQ)
!
      INTEGER*4 I
      REAL*10   C
!
      C = 0.
      DO I = 1,NEQ
         IF (TMASS(I).EQ.0) CYCLE
         C = C + T1(I)*TMASS(I)*T2(I)
      END DO
      ORTHOG = C
      RETURN
!
      END FUNCTION ORTHOG

Unfortunately, it is only supported in 32-bit and can not be vectorized. I have learned to live without the slight improvement in precision, which did slightly improve the convergence. With SSE and now 64-bit, real*10 is no longer a viable option.

8 Feb 2018 9:18 #21336

John, Eddie,

Thanks for the suggestions.

John, This is pretty large code history of which starts from 80th or even 70th, rewriting it to free format will probably never happen unless fixed-to-free translation will be done automatically. The authors still continuing developing it. BTW, we heard here that you do use gfortran, can you please run this fixed format code where i made two cases one where line i=... starts using spaces and another which calculates j=... and starts with the 8 character long tab. Both exceed the 72 by one character. Sorry, i'm short of implicit none, its delivery was again delayed, devilry was too busy delivering it to other places πŸ˜ƒ

        k1111111111111=0
        k2222222222222=0
        k3333333333333=0
        k4444444444444=0
        kR=0
        kR1= 1
        i=k1111111111111+k2222222222222+k3333333333333+k4444444444444+kR1 ! spaces 
	j=k1111111111111+k2222222222222+k3333333333333+k4444444444444+kR1 ! tab 

        if(i.eq.1)  then
          print*,'Spaces: Compiler accepts >72'
        else if(i.eq.0) then
          print*,'Spaces: Compiler does not allow go over 72 char'
        else
          print*,'Spaces: This is the devilry from the hell'
        endif 

        if(j.eq.1)  then
          print*,'Tab:    Compiler accepts >72'
        else if(j.eq.0) then
          print*,'Tab:    Compiler does not allow go over 72 char'
        else
          print*,'Tab:    This is the devilry from the hell'
        endif 


        end
8 Feb 2018 9:50 #21338

Dan,

If I copy your code, insert a PROGRAM statement, and put a tab instead of spaces before j=, then I get '... does not allow ...' for both i and j. With WIDE_SOURCE I get '... accepts ...' for both. What I would expect.

(v 8.10, 32 bit)

Eddie

8 Feb 2018 12:00 #21340

Hi Dan, I inserted a tab before j= I ran using gFortran 7.2.0 from PLATO and got a message 'Compiler does not allow go over 72 char' for both space and tab.

HOWEVER, there are no tab characters in the code I copied from your post, into both PLATO and Notepad.

So, I copied text from forum to notepad, inserted a tab character before j= and saved the file as dan_tab.for. (Notepad displayed I= and j= as lined up) I compiled the file using: gfortran dan_tab.for -o dan_tab.exe

running gives: Spaces: Compiler does not allow go over 72 char Tab: Compiler accepts >72

So gFortran places less than 5 blanks ( probably tabs to column 7)

I would recommend that you create a program that uses stream input and identifies tab characters and replaces them with spaces, based on the rules for gFortran and iFort. I think for fixed form code, the rule is if the tab is in columns 1:5, move next character to column 7. (What happens if the line is a continuation ?)

You can't work with tab characters if your IDE (Plato, Notepad or what ever) does not have the same tab interpretation as your compiler: gFortran or FTN95. I can send you my stream input scan_file program that reports all <HT> characters if you wish. It would not be too hard to write the rule you want to replace <HT> by the variable number of spaces.

Note FTN95 OPEN has a default to replace all tab characters, so you must call READ_TABS@(unitno) to turn this off or use stream/transparent I/O

The <HT> character is not in the Fortran character set. It's interpretation is not portable between gFortran or ifort and FTN95, nor between most IDE's I use. I don't use it in .for or .f90 code.

8 Feb 2018 6:55 (Edited: 8 Feb 2018 11:04) #21347

Thanks Eddie and John. OK the conclusion is that Tab interpreted by the gfortran differently then 8 spaces as Paul suggested. Will look further if i missed something in the faulting cases where besides tabs the spaces were used. May be adding FTN95 option for changing Tab size will look reasonable, what all you think? Unfortunately all people use tabs and will use tabs even by mistake. I had no single problems with 8 character tab for the entire life since FTN77 and perobably earlier starting with DEC VAX and even PDP 11/70. Never had problems with Microsoft Fortran or Compaq one. I'd say this issue never surfaced before with Fortran sources and any compilers (it's devilry's 100% rate of success to trick and hide πŸ˜ƒ )

The code is the result of 40+ years of development by the bunch of people and editors. I'd prefer not to touch myself this issue but probably will write to authors and they have to resolve it otherwise this will be my job again and again with each new version. In general these issues are rare even with gfortran, may be 30-50 cases for 200000 lines of code and great mighty FTN95 pests them off all

Also the forum has to address the tab issue: instead of placing some arbitrary tab it killed the tab in my code above completely substituting it with spaces (?). May be it has to warn of using tabs in CODE section

8 Feb 2018 7:21 #21348

When cards were used, the TAB character didn't mean anything as the column of holes was punched at a physical position. If you had ever used punched tape, on the other hand, you would have come across this issue before. It also reared its ugly head with terminal access systems before the PC. As far as I know, TAB has never been standard-conforming Fortran, which is a pity really, because it is potentially useful, and more so if you don't use statement numbers, but program with lon lines and indentation.

Eddie

9 Feb 2018 12:39 #21352

Dan,

I looked in the Intel documentation and it provides a 'Tab-Format Lines', which basically tabs to column 7. There are special cases for continuation, comments and statement numbers. For tabs past column 7, it treats the tab character in a statement field the same way it treats a blank character. (assuming single blank for column 72 problem ?) This could be confusing, as most IDE's will replace with multiple spaces.

Look at the following link for more details. https://software.intel.com/en-us/fortran-compiler-18.0-developer-guide-and-reference-fixed-and-tab-source-forms

I am not sure about gFortran. I would expect it would replicate the Intel tab format lines. The gFortran documentation states: 'By default, tabs are accepted as whitespace, but tabs are not members of the Fortran Character Set. For continuation lines, a tab followed by a digit between 1 and 9 is supported. β€˜-Wtabs’ will cause a warning to be issued if a tab is encountered.' gFortran also has some other useful command options, including -ffixed-line-length-n -ffixed-line-length-none -ffree-line-length-n -Wtabs

I am puzzled about the 20-year development of this code. Have they lived in a bubble all this time and never converted to other O/S or compilers ?

I could think of some options for FTN95, such as line_length (and also heap_arrays) which would be useful, although they go to the same non-portable problem

John

9 Feb 2018 8:09 #21355

John, This code worked under a dozen Fortran compilers if believe their MAKE utility.

What do you think about Paul's offer to make an option to treat the Tab in the sources as 6 characters long? Wouldn't it be ideal for gfortran fixed format sources compiled under FTN95? Somehow in the entire life I saw 8 spaces tab (older typewriters allow to change that and I remember I used less than that) but 6 would be completely logical for Fortran given its devoted 6th continuation column

With the free format sources tab has no big sense to standardize. But I could be wrong. Like you I often avoid tab in such sources.

9 Feb 2018 8:31 #21356

The /TABS option has been added to FTN95 and Plato has been adapted so that it uses /TABS with fixed format files with the result that FTN95 becomes compatible with the Plato tab setting.

9 Feb 2018 11:28 #21364

I think a good approach for /tab would be to do as gFortran has done and replicate the Intel 'Tab-Format Lines' approach.

What is also necessary is that FTN95 and PLATO have the same interpretation of equivalent spaces for <HT>. With this approach, this post would not be necessary as the position of column 73 would be clearly displayed.

Perhaps a better warning of the line format, such as containing <HT> or lines that don't end in <CR><LF>.

The list could continue ...

9 Feb 2018 11:43 #21365

John

I am not familiar with 'Tab-Format Lines' and what does <HT> mean?

The extension to configurable tab size was easy to implement but I am not contemplating anything further. Presumably it only relates to fixed format which means legacy code.

9 Feb 2018 1:16 #21366

Quoted from PaulLaidler

I am not familiar with 'Tab-Format Lines' and what does <HT> mean?

<HT> is simply a mnemonic for char(9), 'horizontal tab', '\t' in C. Tab (ASCII 09, ctrl+I) characters in source and data have always caused trouble. I get rid of tabs from source files before compiling and from data files before reading them in a program.

The much less used vertical tab (except on line printers) <VT>, '\v' in C, is similar, but is rarely at issue. Likewise for the form feed character.

Here are two places where the widely used conventions for tabs are described:

 https://software.intel.com/en-us/node/692006

 https://docs.oracle.com/cd/E19957-01/805-4941/z40000a545d9/index.html

There are utilities for converting files with tabs:

 http://fortranwiki.org/fortran/show/notab

 http://fortranwiki.org/fortran/show/expand
9 Feb 2018 2:14 #21368

Thanks for this.

9 Feb 2018 2:15 #21369

Quoted from JohnCampbell

I looked in the Intel documentation and it provides a 'Tab-Format Lines', which basically tabs to column 7. There are special cases for continuation, comments and statement numbers. For tabs past column 7, it treats the tab character in a statement field the same way it treats a blank character. (assuming single blank for column 72 problem ?) This could be confusing, as most IDE's will replace with multiple spaces.

Look at the following link for more details. https://software.intel.com/en-us/fortran-compiler-18.0-developer-guide-and-reference-fixed-and-tab-source-forms

It also notes:

NOTE If you use the sequence number field, do not use tabs anywhere in the source line, or the compiler may interpret the sequence numbers as part of the statement field in your program.

I would use ISPF-style editor, like SPFLite on Windows to work with fixed format source files. You can set tabs and column markers and just type away, plus there are a lot of commands to help work with fixed format source files.

For an example, you could type command: EX ALL; SHOW P'=' 73 80 ALL

It would show all the lines using sequence number field and hide the rest.

Please login to reply.