Silverfrost Forums

Welcome to our forums

Find current directory

24 Jan 2023 11:27 #29857

Anything wrong with this code ?

module mod1
character*256 CurrentDirectoryName, CURDIR@
contains

integer function aa()
  CurrentDirectoryName = CURDIR@()
  aa = 2
end function

end module
!-------------------------------------------
program A
  use mod1
  i = aa ()
  print*, trim(CurrentDirectoryName)  
end

while this one works OK:

character*256 CurrentDirectoryName, CURDIR@
  CurrentDirectoryName = CURDIR@()
  print*, trim(CurrentDirectoryName)  
end

Very useful function but causing me headaches for decades.

24 Jan 2023 11:48 #29858

Try this instead:

module mod1
character(len=256) CurrentDirectoryName

contains

integer function aa()
  character(len=256) CURDIR@
  CurrentDirectoryName = CURDIR@()
  aa = 2
end function

end module
!-------------------------------------------
program A
  use mod1
  i = aa ()
  print*, trim(CurrentDirectoryName) 
end
24 Jan 2023 2:05 #29859

hack :lol:

But what's wrong with my code? I lost a half day with it again. Causing crashes, spurious diagnostics in different places...

24 Jan 2023 2:52 #29860

The compiler needs to be informed that CURDIR@ is an external function.

character*256,external::CURDIR@

24 Jan 2023 3:31 #29861

CURDIR@ is external??? Very anti-intuitive. Should we declare now all Silverfrost function with @ as external?

Though may be formally we have to declare as external all of them if use them with external compilers...

24 Jan 2023 10:03 #29862

I find this confusing. If the EXTERNAL declaration is required in the module in Dan’s code, why is it not also necessary in my modified version of Dan’s code?

24 Jan 2023 11:27 #29863

When an identifier appears in an expression with an argument list (with zero or more arguments), and the variable has not been declared to be an array, the identifier implicitly acquires the EXTERNAL attribute. This is why Dan's second version of the code in the first post does not require an EXTERNAL declaration for CURDIR@.

In the first version of Dan's code, the type declaration (character *xxx) and the appearance of CURDIR@(), i.e., variable followed by argument list (empty in this case) do not occur in the same scope, hence the need for a separate EXTERNAL declaration or an interface block.

25 Jan 2023 7:18 #29865

yea...this is obscure and is not a fun to hear for average programmer (and Fortran programming particularly with FTN95 supposed to be fun, isn't it?) . How about creating another such function which will not be error-prone no matter how you use or abuse it?

25 Jan 2023 7:48 #29866

Ken

In your version CURDIR@() appears on the RHS of an assignment within the function that is currently being compiled. This is enought information for it to assume that it must be an external function.

In Dan's 'failing' code, CURDIR@ intially looks like a module variable and the compiler does not scan ahead to see how it is used within the module routines.

25 Jan 2023 10:02 #29867

Mecej4, Paul,

Thank you both for your explanations. I understand what is happening now.

I knew how to make Dan’s first example work – the result of brute force testing to find what works years ago, without really knowing very much about the language rules or considering what the compiler does. Still learning 😄

Ken

25 Jan 2023 12:39 #29868

The scoping rules in Fortran are somewhat complicated, because new facilities (contained subprograms, modules) were added piecewise over decades, while insisting on keeping old programs unaffected by the new features.

A very similar question to the one of this thread may be seen in a thread from 2016 here:

https://stackoverflow.com/questions/40696534/scoping-rules-for-variable-and-functions-in-contained-subroutines

25 Jan 2023 1:50 #29869

Steve Jobs would not approve such solution in the language for things simple like 2x2. Most basic elementary things do not have to require hacking or knowledge of scoping. This is same sort of things, even more simpler, like OPEN file, pity Fortran Standard does not seem to think this is the case. This narrow vision makes Fortran limped and irrelevant to modern use. And the utter example of Standard's blindness was the slow adoption of parallelization so that the third parties MPI and OpenMP are still dominating this field

But what was most confusing here is the Salford/Silverfrost specific @. Not in 100 years i would expect declaration of external for this function 😃

I am sure i will return to this problem in a few years. I see people already had problems with this darn function until like Ken or me after hours of hacking found some shady workaround.

Please login to reply.