Silverfrost Forums

Welcome to our forums

FTN95 fails to compile code with ASSIGNED GOTO

7 Mar 2018 2:58 (Edited: 8 Mar 2018 12:53) #21581

ASSIGNED GOTO was deleted in Fortran 95, but FTN95 still supports this. Here is a test program that various versions of FTN95 (and even FTN77) fail to compile.

      program tasg
      implicit none
      integer i,ka
      i=3
      print *,ka(i)
      end

      function ka(i)
      implicit none
      integer i, ka
!
      ka = 0
      if(i.eq.2)then
         assign 10 to ka
      else
         assign 20 to ka
      endif
      goto ka
   10 ka = i*i
      return
   20 ka = i+i
      return
      end

The error message given by FTN95 8.10:

0014)          assign 10 to ka
*** Only INTEGER(KIND=3) variables may be ASSIGNed to

This is surprising since ka is a default integer and, therefore, of kind = 3.

The correct output produced by running the program is '6'.

It will be perfectly fine to give this bug low priority or to mark ASSIGNed GOTO and Format labels as 'deleted' in FTN95. On the other hand, there are still codes in use (such as older versions of the BLAS ?NRM2 function) which contain the Assigned GOTO.

The bug is not encountered if the selector variable does not have the same name as the function.

7 Mar 2018 10:41 #21582

Is the issue that ASSIGNed GOTO doesn't work, or that you can't (or shouldn't) have a variable with the same name as the function that it's in?

For example:

      program tasg_a 
      implicit none 
      integer i,ka 
      i=3 
      print *,ka(i) 
      end 

      integer function ka(i) 
      implicit none 
      integer i, ka(10)
      ka = 5*i
      return 
      end

which gives the answer 56687628, which certainly isn't 15. (v8.10, 32bit)

Personally, I'd never use a subprogram name as a variable (I thought you couldn't), but surely FTN95 ought to declare a warning that doing so is likely to produce odd results, and I'm more worried by my example succeeding without demur than I am by yours failing.

Eddie

7 Mar 2018 11:19 #21583

The deleted ASSIGN statement is peculiar. In a single program unit, you can have a scalar integer variable be one of (i) a scalar integer variable, (ii) a statement number that can only be used as the target of a GOTO, (iii) a Format statement number that can be used in an I/O statement. The programmer is supposed to know the nature of the current value of the variable. If the variable has an ordinary integer value (not a statement number), you should not use that variable in a GOTO or as the format no. in an I/O statement. If the variable is currently assigned a statement number, you should not use it in an arithmetic expression.

...

Your program contains a function that returns an array-valued result, and for such functions an explicit interface is required. The implicit interface is used by the compiler, and the program malfunctions. The function probably returns a pointer to an array, but your main program thinks that what is returned is a scalar integer.

Compiling with /check should have caught the missing interface.

Within the function code, you have two type declarations for ka, which is not allowed and the compiler should have flagged that as an error.

Here is a corrected version.

      program tasg_a                                                                                                                        
      implicit none                                                                                                                         
      integer i                                                                                                                             
      i=3                                                                                                                                   
      print *,ka(i)                                                                                                                         
      contains                                                                                                                              
                                                                                                                                            
      function ka(i)                                                                                                                        
      implicit none                                                                                                                         
      integer i, ka(10)                                                                                                                     
      ka = 5*i                                                                                                                              
      return                                                                                                                                
      end function                                                                                                                          
      end program 

Personally, I'd never use a subprogram name as a variable.

I am sure you do -- whenever you write code for a function subprogram and do not append a RESULT (<variable>) clause to the FUNCTION line.

8 Mar 2018 11:09 #21584

Mecej4,

You are being mischievous, as I suspect you know what I meant, and the function name isn't an ordinary variable useful for a variety of other things, such as jumping around the code, labelling FORMAT statements or anything else you care to mention.

Whatever was wrong with what I wrote, it neither generated a compiler or run-time error, which was ultimately the point - it just gave a daft answer. And all because the simplicity of proper Fortran was debauched.

'Fortran 90: nice language, too bad it's not Fortran' (Dan Davison - not that I'm personally acquainted with the gentleman).

E

8 Mar 2018 2:14 #21587

It may be bad style to use a function name for other things in the corpus of that function, but as far as the language is concerned, with one or two exceptions, you are free to use the function name as you would use any local variable. For example:

program tfname
implicit none
integer i,n
   do i=5,10
      n = fact(i)         ! fact: internal function name
      print *,i,n
   end do
   stop
   
contains

   integer function fact(i) ! function name
   integer i,j
   fact = i                       ! return variable initialised
   j    = i
   do while (j > 1)
      j = j-1
      fact = fact*j             ! fact used same way as local scalar integer
   end do
   return
   end function

end program

is bad in style and may give a compiler a hard time, but it is legal. Sometimes, we run into such code written by others, and such code has a place in a suite of testcases for 'torture-testing' the compiler.

By the way, since this thread is about ASSIGNed GOTO, I may mention something that I just learned: almost no PC compiler provides debugging support for code containing ASSIGNED GOTOs. That fact should motivate one to get rid of ASSIGNED GOTO as soon as possible, because the deficiency is probably not worth rectifying at this time.

For the duration in which the variable is associated with a statement label, a debugger (not necessarily SDBG) may show (i) the address of the label (which is probably the explanation for your observing 56687628), (ii) an index into a list of labels that will be used in a subsequent GOTO <var>{<(list of labels)>)}, or (iii) nothing. Some compilers cause the variable to remember a previously assigned integer value, which I think is misleading.

8 Mar 2018 2:44 #21588

I will make a note of this omission although I am not sure that the work required to add this feature is warranted. Was this construction (using an ASSIGN statement to deliver a function return value) ever included in a Fortran standard?

8 Mar 2018 3:37 (Edited: 10 Mar 2018 12:28) #21589

Quoted from PaulLaidler I will make a note of this omission although I am not sure that the work required to add this feature is warranted. Was this construction (using an ASSIGN statement to deliver a function return value) ever included in a Fortran standard?

Paul, it does not deliver a function return value.

Section 8.2.4 of the F90 standard describes ASSIGNed GOTO, and explains the multiple personalities of an integer variable that is assigned (i) a scalar integer value, (ii) a statement label of an executable statement in the function, and (iii) a Format statement label. When one of these three associations is current, the other two associations are suspended.

Section 12.5.2.2 describes how a function subprogram should work with or without a RESULT(resvar) suffix in the heading. In that section, it says 'If RESULT is not specified, the result variable is function-name and all occurrences of the function name in execution-part statements in the scoping unit are references to the result variable. The value of the result variable at the completion of execution of the function is the value returned by the function.'

Thus, we have to interpret the test program based on both sections: 8.2.4 and 12.5.2.2.

There is a current thread on Comp.Lang.Fortran on this topic: https://groups.google.com/forum/#!topic/comp.lang.fortran/zCqVH61EQO8 .

Thanks for your patience and interest.

8 Mar 2018 3:46 #21590

Paul,

I think that Mecej4 has at least hinted at the answer - no, it isn't worth doing - but if you could detect the original error, you might consider providing a more informative error message. It seems to me that FTN95 does not always consider a FUNCTION name to be a simple INTEGER of default KIND=3, regardless of what the standard may or may not say.

FTN95 appears to deal with ASSIGNED GOTO perfectly well in a subroutine, so that probably needs no action.

Mecej4: would you agree?

I'm not sure that I would use such gymnastics to get a function return value, instead working it out with other variables and assigning it immediately before the RETURN that appears no longer to be required - primarily because I didn't know you could use it in the way you have!

Legality is not always the ultimate test of probity.

Eddie

8 Mar 2018 4:16 #21591

Quoted from LitusSaxonicum Paul,

I think that Mecej4 has at least hinted at the answer - no, it isn't worth doing - but if you could detect the original error, you might consider providing a more informative error message. ... Eddie

I agree with that. Here are some things that could be done: (i) does the current subprogram contain assigned GOTO statements? (ii) if so, is it a function? (iii) if so, is the function name the same as the assignee variable?

If the answers are 'yes', 'yes' and 'yes', suppress any pending error messages and issue a message saying that the compiler cannot handle this construction (symbol overloading involving a deleted language feature), and suggest that the user change the variable name and try again. A single 'no' implies that the compiler is capable of processing the code, and it proceeds as it does now.

Simply changing the wording of the error message from 'Only INTEGER(KIND=3) variables may be ASSIGNed' to something more appropriate would also suffice.

8 Mar 2018 5:03 #21592

I understand that my statement was not strictly correct but ka is associated both with an ASSIGN and with the function return. I will take a look to see if the restriction can simply be removed without further work being entailed.

8 Mar 2018 5:56 #21594

Quoted from PaulLaidler ... but KA is associated both with an ASSIGN and with the function return.

Yes, but not simultaneously! There are some similarities with the Pascal variant record type. And with EQUIVALENCE(J,R,D), where J is integer, R is real and D is double precision, and only one of the three can be defined at any time.

I will take a look to see if the restriction can simply be removed without further work being entailed. That would suffice. Thanks.

8 Mar 2018 8:58 #21595

...suggest keeping the original message too ...

Why would you want to keep the original message, which is wrong?

The types of the variables are all fine, and the program has no errors. The compiler was just not prepared for the function name to be used as a statement label variable, got confused, and gave an incorrect error message.

Please run the code with another compiler than FTN95 to see that there are no errors.

s:\LANG>lf95 asgerr.f
Lahey/Fujitsu Fortran 95 Express Release 7.10.02
Copyright (C) 1994-2004 Lahey Computer Systems.  All rights reserved.
Copyright (C) 1998-2004 FUJITSU LIMITED. All rights reserved.
Compiling file asgerr.f.
Compiling program unit tasg at line 1:
Compiling program unit ka at line 7:
Encountered 0 errors, 0 warnings in file asgerr.f.
Microsoft (R) Incremental Linker Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.


s:\LANG>asgerr
6
9 Mar 2018 8:12 #21596

It turns out that the addition of this feature would be non-trivial.

So the message has been clarified and will now give...

The use of the function result (KA) in an ASSIGN statement is not supported
9 Mar 2018 10:38 #21597

John S,

I am ok with FTN95 not being changed to support that a function name/variable can be used for an ASSIGN variable. After all the use of ASSIGN is now obsolete and so not recommended.

I do understand mecej4's problem, in that it is legal Fortran that is contained in legacy code, although I am not sure how extensive. Making KA to KAS for the assign could easily overcome the problem (with the more informative error message) if this was an isolated use of this approach.

9 Mar 2018 11:31 #21598

Quoted from John-Silver (i) I thought the root reason was that the compiler was being confused with the declaration of a variable with the same name as the function name ... (ii) to be honest the whole post has confused me to bits, especially trying to work out how the correct answer to the original code is 6. Shouldn't it be 4 ?

(i) No, as you can see in my reply to Eddie's second response in this thread. There, I showed code for a function that computes the factorial. The name of a function that returns a scalar value can be used as a local variable in the body of the function, in more contexts than result assignment.

(ii) The function is referenced with i = 3. The test 'i.eq.2' fails, and the label 20 is assigned to ka. The assigned GOTO statement causes a jump to label 20, where the assignment 'ka = i+i' is carried out. Since i = 3, ka is assigned the value 6.

I do not know how you concluded that ka should have been equal to 4.

10 Mar 2018 1:56 #21599

If the feature (ASSIGNed GOTO) was actually deleted in Fortran 95 et seq., then it is retained in a Fortran 95 compiler only as a favour to users, and isn't strictly legal, code-compliant, Fortran 95. (I say 'if' because that's what I read in various websites, but it may not be correct).

I think my position on retaining old features is clear, but then an ASSIGNed GOTO was always a rather crass thing in the first place, and surely has never been a commonplace feature of most people's source code.

Now there's something about the name FTN95 that may be of relevance here, but I can't put my finger on it just now. I wonder what it is?

Eddie

10 Mar 2018 4:06 #21600

Eddie, I don't think that I can do better than to repost an exchange on this very question between two rather prominent people recently. One (A) is the author of a text book on Fortran published by Springer. The other (B) is a member of the Fortran Standards committee.

Quoted from A In the 25+ years since F90, it has been replaced by several newer standards, and therefore implementing something in an F90 compiler seems to be a waste of effort, especially since (a) the code is useless, and (b) the code is now illegal.

Quoted from B (a) doesn't matter to customers (b) is incorrect. It may not be valid F2003 or later, but in the real world, compilers that don't properly handle F77 and later are market failures. I'd go so far as to add F66 to that. As I wrote, a compiler that claims to support F90 needs to be able to correctly process any valid F90 source.

Some current Fortran compilers let you specify -std=f77, -std=f90, -std=f95, etc., thereby controlling which standard is used in deciding the warnings and error messages to issue.

Even if one wishes to redeem oneself by removing ASSIGN from a legacy code, exorcising the ASSIGNed GOTOs requires a compiler that can compile the old code correctly, if one wishes to have some assurance that the modified code gives the same results as the old code.

We have, in fact, two failed compilers that prove the point made by 'B'. Both were subsets of Fortran 90/95: Lahey's ELF90, and Imagine1's F.

10 Mar 2018 8:54 #21602

Springer seem to have published quite a few books on Fortran ...

12 Mar 2018 12:53 #21603

Quoted from John-Silver ... to be strictly true shouldn't that message have ... 'in ftn95' at the end ? ... as I thought it runs ok in other compilers.

It is not easy for a compiler to emit a meaningful and pertinent error message. For the test program that I posted, the NAG compiler says:

Obsolescent: salasg.f, line 1: Fixed source form
Deleted feature used: salasg.f, line 14: ASSIGN statement
Error: salasg.f, line 14: ASSIGN to function name KA is not supported

which is very well said. On the other hand, the venerable F2C from AT&T Bell Labs says:

salasg.f:
   MAIN tasg:
   ka:
Error on line 12 of salasg.f: out_asgoto:  bad expr

This tells me where the problem is, but the rest of it may be understandable only to the compiler writers.

Please login to reply.