Silverfrost Forums

Welcome to our forums

Curiocities

25 Mar 2015 11:22 #15987

Want me to show you true pure example of programming devilry again? Here is one damn error resolved at 4 am:

11800)           Ctbr_Sum = Ctbr_Sum + RELABex(j,IZSp1,III)* Ct_Hull(j,i,IZSp1)/
11801)      *    (RELABexSUM(IZSp1,iii)+1.e-7)
*** ':' found where not expected
*** INTEGER expression expected in substring range

Where the hell here is this damn colon? Or Integer expressions? The fun was that exactly next lines in this log file were the following

12149) 6666    b = A_exc_HULL(6,I,J,IZS)/TE_llnl
WARNING - Label 6666 is declared, but not used
11606) 66666   b = A_ion_Hull(6,I,J,IZS)/TE_llnl
WARNING - Label 66666 is declared, but not used

And even more - you think i actually eventually found the error? Not at all, after some time of harassing me it disappeared by itself!

And even that was not all. I decided to save this whole compilation log file for history because no one will believe me. And to find myself what was going on. But when i hit Ctrl+S the application of text viewer crashed with access violation. But the text was left on screen. I eventually succeeded to save it together with Fortran text and its BAK file. There is no colon there but the old BAK file does not compile!

May be somebody see here what i do not see?

25 Mar 2015 2:12 #15989

For me this code fragment compiles without error. Perhaps we need more code in order to comment.

28 Mar 2015 8:38 #16018

Exactly. 😃 As to believe or not - look at the continuation, this is interesting. Further investigation when computer compared two files instead of my faulty human eye revealed that these two lines in these files are different:

http://s25.postimg.org/5eiew2zkf/Devilry_Compar.png

Upper part is defective, lower is not.

Binary comparison of these lines showed presence in defective file just one more ascii symbol hex 20 which is integer 32 ... which is just the space and nothing else

I checked that additional symbol does not expand the line beyond 72 symbols long, so that is not a reason of a problems.

I extracted this piece sans 666 part into small code and post it here. It produces exactly this error report. Try it yourselves and see if devilry disappears. This forum unfortunately destroys fixed fortran formatting and you may not get the effect. I can post this file zipped then

        integer NUMBlevsZ (100)
        real*4 RELABex (100,100,100)
        real*4 Ct_Hull (100,100,100)
        real*4 RELABexSUM (100,100)
 
	DO  i = 1, NUMBlevsZ (izs)
 	  Ctbr_Sum = 0
	  Do  j = 1, NUMBlevsZ (izs+1)
	  Ctbr_Sum = Ctbr_Sum + RELABex(j,IZSp1,III)* Ct_Hull(j,i,IZSp1)/
     *    (RELABexSUM(IZSp1,iii)+1.e-7)
	  enddo
	enddo
	end

UPDATE: OK, to keep the experiment clean here is zipped file i posted on Microsoft OneDrive website:

http://1drv.ms/1Mf7XvO

Just compile it and see the devilry yourselves! It's just the text file so nothing to worry about. Besides the devilry

28 Mar 2015 12:30 #16019

The devil's in the ASCII -- your source file has tabs. Replace them by spaces (most text editors can do that, or you can use the FTN95 /convert option) and your devils will have been put to bed.

Next time when you are typing in a program, make sure at first that your text editor is set to replace input tabs by spaces.

You can expect similar problems if other 'whitespace' characters (reverse-tab, backspace, delete, form feed, ..., irregular combinations such as LF+CR) are embedded in your Fortran sources.

28 Mar 2015 7:59 (Edited: 29 Mar 2015 6:01) #16023

Let we investigate this suggestion a bit more since it sounds like an over-forcing to my style of programming. I always reasonably - mostly for indentation if this is correct english word for beginning of line formatting - used tabs with no problems, they are still used with working file with no problems and fun is that I did not touch the offending part of the file for decades to cause this problem. Tabs were used with DEC, Cray, MS, Compaq Fortran compilers in the past with this same code as it was evolving over all these years. Binary comparison also shows that the space was added to offending line not the tab. I afraid we will throw the child, I mean devilry, with the water and it will appear again 😃.

So, first, can you guys with other compilers check how they compile this broken code?

29 Mar 2015 8:26 #16025

...why is that? An occurrence of a variable followed by a list of arguments within parentheses is taken to be a function reference if the variable is not known to be an array. Try linking the object file. No surprises here.

Had IMPLICIT NONE been specified, an error message regarding the type of RELABEXSUM would have been issued.

29 Mar 2015 10:51 #16028

Mecej4,

Would IMPLICIT NONE bring up an error if the array was in fact a function reference? Why should it? I can see that an EXTERNAL function might need to be explicitly typed so that when it is used as an argument in a call its type is clear (for example the callback in WINIO@), but the type of non-EXTERNAL functions is presumable decided later.

If it did elicit an 'error' message, surely it should be a warning rather than an error, as there would still be the opportunity for it to be a function.

I suspect that it takes more than IMPLICIT NONE to resolve this.

As a real oldie, I have to confess that IMPLICIT NONE simply makes code unreadable to me (especially in combination with F90 formatting) - so it takes all sorts!

I think that I discovered that the TAB character stopped being useful when I moved from terminal access to a VAX 780 to my first PC, c. 1983, with Microsoft (Yah, Boo, Hiss) Fortran version 3.1, and I converted them all to spaces with WordStar in 'non-document' mode. My memory of this is hazy, but didn't the VAX map the first tab to column 7 and after that to multiples of 8 or 10? Other systems didn't, and lost valuable character positions in fixed format! I'm astonished that Dan got away with it for all this time, so perhaps the 'devilry' is, in fact, 'original sin'!

Eddie

29 Mar 2015 11:25 #16029

Eddie,

Unless there is a type declaration for a function within scope, when IMPLICIT NONE is used or the /IM compiler option is used, the result is an error message. Often, one adds IMPLICIT NONE to order the compiler not to apply implicit typing rules, thereby making explicit type declarations mandatory. In fact, FTN95 says this about Dan's code:

0009)      *    (RELABexSUM(IZSp1,iii)+1.e-7)
*** RELABEXSUM must appear in a type declaration because IMPLICIT NONE has been used

The use of tabs is an extension. Here is one vendor's specification of the rules for expanding tabs: http://docs.oracle.com/cd/E19957-01/805-4941/6j4m2sobi/index.html . I do not know if FTN95 has similar written rules.

Original sin? We do not need to hark back to Adam, the snake and the apple. Dan chose style over substance, and probably has a mess of it to handle. Fortunately for him, all that he has to do in expiation is to run his source code through a filter or to use FTN95's /CONVERT, and request the compiler to accept wide lines (expanding tabs can cause some lines to end to the right of col-72 or col-132). I think that is is wrong to shop for a compiler that will accept buggy code and produce correct results.

29 Mar 2015 4:19 #16030

why isn't it complaining that the function doesn't exist That is not the compiler's prerogative. Fortran has the associated concept of separate and independent compilation. The source code of a program can be spread across a number of files. The function subprogram may reside in a different file than the source containing its invocation. In fact, the function may not even be available in source form, but in a precompiled library or DLL. When the compiler is processing one source file, it need not have any awareness of the contents of other files (unless modules are being USEd).

It is at link time that undefined external symbols get reported.

29 Mar 2015 4:23 #16031

The function will be declared as missing at link time. For an error report at compile time try using the command line option /DCLVAR.

29 Mar 2015 10:57 #16032

Just on the comments about the use of tab characters:

I find it very annoying when tab characters are used in fixed format Fortran code, as the different editors I use do not use the same tab spacing definitions. I have been reviewing code recently, where in the editor I am using (Plato or notepad), the use of a tab character moves code to column 5, where the original IDE (probably VS) moves the character to column 7. This is a problem when viewing the code in different IDE/editors and I am not sure what FTN95 or other compilers do with this code, which is another more important problem.

It is this poorly defined response to tab spacing that suggests to me that there should be a compiler option to report tab characters as an error. I think that they are not in the Fortran standard character set for code and their presence could change the action of the code, especially in .for files. Code that uses tab characters should have a header to define the tab spacing rules.

I have even written my own code viewer that replaces all control characters, especially <HT> <CR> and <LF> to identify these problems.

John

29 Mar 2015 11:34 #16034

Not declared variable is not related issue. When extracting the line into the test code i just forgot to declare one variable which i thought is still irrelevant. It was declared in the posted code on this forum above by the way. Anyway, this code has 200000 tabs and never had any issues for 37 years with any compiler. Same with other large code written by colleagues and compiled on a half a dozen different compilers on PC, Unix and Mac. So, returning to our devilry -- what specifically caused compiler to issue this exact error report?

Respect to John's comment, few years back when i tried Plato i made a suggestion on this forum to discuss making the tab user-definable separately for fixed and free source codes. Have both types of sources in the same code but Plato does not automatically recognized them making Plato useless for me. This suggestion would solve all the tab problems i think. Substitution of tabs with respective amount of spaces option could be also useful as a bonus.

30 Mar 2015 6:47 #16036

Dan,

Still on the tabs; It is one problem to have Plato (or other IDE's) interpreting the tabs, but what does FTN95 do with tabs, especially in .for files ? After all, it is what the compiler does that is important.

Ban tabs !! (or make their interpretation standard)

John

30 Mar 2015 7:17 #16037

FTN95 replaces a tab character by 8 spaces and this does not depend on the column position. FTN77 will be the same.

Plato and VS can be configured for different tab sizes and to replace tabs by spaces as they are typed. In this case the tabs are expanded depending on the column position. In Plato you can have different settings for fixed and for free format files. See the Options dialog on the Tools menu.

As far as I can remember configurable tabs have been available in Plato since version 3 (i.e. a long time ago).

Plato also has a command to replace all existing tabs in a file by spaces. By default this command does not have an associated accelerator key so you will need to open the Option dialog box, select Environment then Keyboard and look for Edit.ReplaceTabs. You can then choose your own accelerator key for this. I have it set to Ctrl+R.

I will make a note of John's request for tabs to be rejected via an FTN95 command line option.

30 Mar 2015 9:25 #16039

Now that Paul has clarified that FTN95 treats each tab character in input source as eight spaces, Dan's problem becomes well-defined. Note that the replacement is not done if the tab character is part of a string constant.

If Dan chooses to keep tabs in his source files, it becomes Dan's responsibility to ensure that each source line, after replacing each tab with eight spaces, is

 (i) valid Fortran source that does not cross the right boundary (beyond column 72 in fixed form and 132 in free form), and 

(ii) the semantics of the source after tabs are converted are the same as those that Dan intended.

Statements that are long and are spread over several continued lines may need correction if they contain tabs. Since such statements are not likely to be pleasing in appearance anyway, it may be best not to use tabs in continued lines.

It would be easy and worthwhile to write a utility program that scans Fortran source files and flags any lines that cross the right margin after substituting for tabs that are not within strings.

30 Mar 2015 9:53 #16040

Intel ifort defines 3 source forms; fixed, free and tab. The tab form appears to be an adaptation of the fixed form and describes a special interpretation of the tab character in columns 1 to 5 then subsequent tabs appear to be associated with columns 9, 18, 27 etc, using an 8 space field. (can't guarantee I have this correct as I have never used this approach.)

I have found when receiving tab form source, other IDE's and compilers do not recognise this source form and so it must have limited portability.

In the old Lahey F95 compiler I have, I can't find any reference to the use of tab characters in source. It may treat it as any number of spaces. If tabs were interpreted as 3 spaces, I probably would have adopted it for DO loop indentation many years ago, but 8 spaces is too much. They simply cause confusion when skipping between IDE's, so my old line editor that I used in 80's removes them.

I am certainly not recommending FTN95 adopts this form, which I can't find in any Fortran standard.

John

30 Mar 2015 11:44 #16041

Tabs are dangerous - I never use them. I nearly always use fixed format due to my advancing age and use the following scheme:

  1. Statement and format numbers have 4 digits: type <space> and the number then <space> and carry on with the line
  2. Continuation lines: 5*<space> <apersand>
  3. Indentation +-2 spaces per level.
  4. Normal lines: 6*<space> then the indentation then the line.

I posted a fix for tabbed files some years ago, see: https://forums.silverfrost.com/Forum/Topic/547&highlight=untab Ian

30 Mar 2015 11:56 #16042

Mecej4, thanks for the clarification. So, if you have IMPLICIT NONE (implicitly or explicitly) then all your function names that are provided in separate source files need to have their type declared somehow? How do you know what is in scope until linking if you have separately compiled files? I'm too old a dog for this new trick.

Dan, TABs were always an extension. On IBM model 26 and 29 card punches, you could press the TAB key, but it always gave you spaces by advancing the card in the punch.

My recollection is that Hollerith cards used a 6-bit code, thus excluding many control characters in the resulting 64-character set. The TAB character wasn't part of the character set. We Brits often used 8-hole punched tape, giving us a 7-bit code allowing 128 characters (the 8th hole was used for a parity check as the punches weren't reliable). This opened up a whole range of extra characters, including control characters, and the adoption of terminal-based systems allowed 256-character codes with even more.

Thus, TAB is original sin, no matter how useful it has been.

Eddie

30 Mar 2015 12:13 (Edited: 31 Mar 2015 12:51) #16044

Quoted from Eddie So, if you have IMPLICIT NONE (implicitly or explicitly) then all your function names that are provided in separate source files need to have their type declared somehow? How do you know what is in scope until linking if you have separately compiled files?

The IMPLICIT statement was added in Fortran-77. Most F77 compilers also supported the MIL-STD-1753 extensions, which included IMPLICIT NONE.

The scope of variables in F77 is the program unit (main program, subroutine, function, block data). This is also true of Fortran 90 and later versions if we do not use modules. Whether the program units are in the same or different files does not matter since, unlike in C, variables are declared inside a program unit and do not have file scope.

Here is an example. Try it as is and then try it after commenting out the type declaration of the function SQR in the main program.

program ximp
   implicit none
   real :: x,y,sqr
!
   x=2.0
   y=sqr(x)
   write(*,*)x,y
end program ximp
!
function sqr(x)
   implicit none
   real :: x,sqr
!
   sqr=x*x
   return
end function

Quoted from Eddie On IBM model 26 and 29 card punches, you could press the TAB key, but it always gave you spaces by advancing the card in the punch. Indeed. You could punch a tab control card with holes in the columns where you wanted tab stops, mount that card on the drum in the keypunch machine (see http://www.columbia.edu/cu/computinghistory/029-drum.jpg ), and from then on each press of the SKIP (=tab) key would advance the punch head to the next tab stop. We used to carry a set of these curled-up cards, one for Fortran, another for Algol, etc. With the Fortran tabs card mounted, after a new card was fed you would press SKIP, and the punch head would then be in column-7 -- a lot quicker than typing six blanks. When you wanted something in columns 1-6, you typed that in instead of pressing SKIP.

30 Mar 2015 12:54 #16045

OK, I see how it reports the error. An education for me.

I can't help but feel that with every passing iteration, Fortran looks more like Algol, but never quite gets there.

Thanks for the reminder about how the tabs were set, I'd forgotten. I preferred the modernist look of the 029 to the Art Deco Cinema look of the 026, but I expect that the guts were the same.

Eddie

Please login to reply.