Silverfrost Forums

Welcome to our forums

Fortran 2003 and 2008 features

12 Aug 2022 6:19 #29269

Thanks. I will add ASSOCIATE to the list.

12 Aug 2022 11:22 #29271

I have seen Dan's example for the use of ASSOCIATE before, and find it very confusing. Why does the second print*, x statement return 1 and not 10 since the value of a is updated in the proceeding line? The final print*, x statement does appear to recognize that a has been updated within the second associate block. What is the difference here - that I cannot see?

12 Aug 2022 12:35 #29272

Ken

I appears that expressions are stored as the constant that they evaluate to (at the point of association), whilst simple variables are treated as targets to the identifier on the LHS which is effectively a pointer.

In the latter case you effectively get a pointer to a variable target with the pointer having a limited scope.

12 Aug 2022 7:38 #29279

Thank you, Paul, I can see that now.

A rather artificial test program to try sometime:

program test
  implicit none
  integer, parameter ::dp=kind(1.d0)
  integer  j
  print*, 'j [i.e. sqrt(-1)] raised to powers 1, 2, 3, and 4'
  do j = 1, 4, 1
    associate( j => cmplx(0.d0,1.d0,kind=dp)**j )
    print*, j
    end associate
  end do
end program test
23 Aug 2022 1:32 #29288

More twists from Fortran language nazis.

  1. Found such pieces in their codes call af_particles_to_grid(tree, i_pos_ion, n_photons, & get_id, get_rw, interpolation_order_to_density, & iv_tmp=i_tmp_dens, offset_particles=n_part_before)

and made simple demo test Program test Real a, b b=1 Call sub1 (a=b) end program

subroutine sub1(A)
Print*,A
End subroutine

which gives the following error report

*** SUB1 has an implicit interface and cannot have keyword arguments (possible 

Is this useful modern Fortran feature or just an usual perversion which makes code unreadable and often just plain slower?

  1. What for IMPORT is used here?

     interface
        !> Function that returns a scalar
        real(dp) function box_func(box)
          import
          type(box_t), intent(in) :: box
        end function box_func
    
        !> Reduction method (e.g., min, max, sum)
        real(dp) function reduction(a, b)
          import
          real(dp), intent(in) :: a, b
        end function reduction
     end interface
    

Is it supported by FTN95 ?

23 Aug 2022 8:00 #29289
  1. The error report in the simple demo test is correct. An explicit interface is required in this context.

  2. IMPORT is supported but it is a recent addition. Please report any failures.

23 Aug 2022 8:29 #29290

Dan,

SUB1 is not an internal routine i.e. contained in the program or a module. As it is an external routine it must be listed in an interface block.

So there are four ways to make this code work:

Add an interface block:

Program test
Real a, b
interface
  subroutine sub1(A)
  real A
  end subroutine sub1
end interface
b=1
Call sub1 (a=b)
end program

subroutine sub1(A)
Print*,A
return
End subroutine

Move SUB1 to a new CONTAINS section in the main program

Program test
Real a, b
b=1
Call sub1 (a=b)
contains
  subroutine sub1(A)
  Print*,A
  End subroutine
end program

Put everything in a module

module demo
contains
subroutine test
Real a, b
b=1
Call sub1 (a=b)
end subroutine test
subroutine sub1(A)
Print*,A
End subroutine
end module demo

program p
use demo
call test
end program p

Put SUB1 in a module and USE the module in the main program:

module demo
contains
subroutine sub1(A)
Print*,A
End subroutine
end module demo

program test
use demo
Real a, b
b=1
Call sub1 (a=b)
end program test
23 Aug 2022 6:33 #29291

Paul, Ken, Thanks but my question was about rationale of doing this unusual and hence confusing thing.

Why not do this obvious way which will not require any trickery with modules, interfaces which are just causing the code to be bloated and less readable?

Program test
Real a, b
b=1
a=b
Call sub1 (a)
end program

subroutine sub1(A)
Print*,A
End subroutine

Or this error was because Fortran does not check subroutine arguments when it is called on types consistency so that the code does not know if A and B are functions or regular variables? If people think that the ability to call sub1(a=b) is an useful addition to Fortran (to make crazy nazis happy or just as a copycats because some other compilers do that why not Fortran?) why not to make compiler to check a and b and in my case allow it go without any interfaces ? Sorry, i might sound dumb, because still for more than a month deciphering one code written as claimed in Fortran 2011 which is like a cryptomachine causing my brain damage 😃. It outputs data in proprietary format SILO for which there is no file converters or viewers for its structure (i can see its visualization content in third part graphics software though, but this is not enough for futher use of code output)

24 Aug 2022 7:36 #29292

Dan

Optional and named/keyword arguments were introduced at the 'beginning' i.e. in the Fortran 90 standard.

24 Aug 2022 2:39 #29293

Hi Paul,

For some of us, Fortran 90 was more like the end than the beginning ...

Eddie

24 Aug 2022 3:36 #29294

Quoted from PaulLaidler Dan

Optional and named/keyword arguments were introduced at the 'beginning' i.e. in the Fortran 90 standard. and they do require an interface definition, either explicitly or via contains, as Ken has outlined.

A lot happened to F95 after F90 !

it is not 'call sub ( a==b )' which would be a different spin,

24 Aug 2022 5:24 #29295

Paul, Seems no one since 1990th used such a=b option and those who used did not ask the question why interface was needed when it is clear that sometimes it is not needed. Was interface required because Fortran compilers back then did not check subroutine arguments for consistency?

Great that Clearwin functions do not require interfaces, that would be a disaster

Eddie, And there also exist linked lists also introduced hell lot ago which will crush not only the human brains but also the brains and cache coherency of pipelines of all predictive branches of processors https://en.wikipedia.org/wiki/Linked_list

John, The question is why they need interface definition? I gave definition for a and b enough for Fortran to run the code unambiguously.

24 Aug 2022 8:10 #29296

Dan,

b=1
a=b
call sub1(a)

Is not the same as

b=1
call sub1(a=b)

as in the second case (a=b) is not an assignment in the 'usual' way. It is showing that argument A is present with value B.

Example: Program test implicit none real b ! No need to define a as real b=1 call sub1 (a=b) call sub1

contains

  subroutine sub1(a)
  real, optional :: a
  if (present(a))        print*,a
  if ( .not. present(a)) print*, 'no a input'
  end subroutine

end program

But the program runs OK, if you omit the optional declaration for A in SUB1 and don't use the PRESENT inquiry function.

24 Aug 2022 8:32 #29297

Ken, As valid by common sense code my example should work. I think it does not work just because possibly not all options were taken into account by FTN95 - no one in 20 years used this super rare twist besides geeks of 80th level, those who were paid by the number of lines of source code adding millions interfaces or those who wanted to make their codes unreadable to 99% fortraneers 😃. I am not insisting to fix this as it looks like there is no any benefits for the codes with this (currently) cryptic syntax.

Or may be writing variables like this
call sub1(a=b) is a good idea and will save us one line of code if it will not require any interfaces/modules/anything and will work like in my demo example which currently does not work.

But something related to better checking of arguments of subroutines still needs a fix as this code prints the result 6.6e-37 while has to write 'no a input'

Program test

call sub1

end program
!----------------------
  subroutine sub1(a)
  real, optional :: a
  if (present(a))        print*,a
  if ( .not. present(a)) print*, 'no a input'
  end subroutine

Definitely by not working and requiring interface (or as you have shown by placing into the module or into CONTAINS) my demo example will confuse the programmer who will not understand why with interface or in module it worked and without did not.

If there will be more detailed error message explaining that the Standard by unknown reasons always requires interface or be in the module for such cases even if all variables are available and declared - hell knows why - then this might help not to lose time trying to find the ends.

Last 6 months i was literally losing time trying to get through similar twists of 'modern' Fortran and so far did not find any rationale for using most of them. More and more i find they are more bad than good for the code readabilty, maintenance and speed.

25 Aug 2022 8:00 #29298

Dan, That's an interesting twist to my last example. Another compiler does issue an ERROR at the call to sub1, 'Explicit interface required for 'sub1': optional argument.

FTN95 with Checkmate does generate a run-time message 'Attempt to call a routine with zero arguments when one is required'. Which I agree does not help to pinpoint the need for an explicit interface.

One for the folks at Silverfrost to consider at some point.

25 Aug 2022 9:32 #29299

gFortran does do better in this respect in that it generates a compile time error.

However, sub1 and the sub-program that calls it could be in separate files. In which case the caller knows nothing about the arguments at compile time and the compiler is unable to do any argument checking.

FTN95 deals with this via the runtime checking of CHECKMATE which may be unique.

As a general rule, sub-programs are separately compiled. If they reside in the same file then the compiler may do some cross referencing and indeed FTN95 does do this in most contexts but apparently not in this case.

For separate compilation and in the absence of an interface, the best that a compiler can do is to check that different calls to a sub-program are consistent in the number and in the type of the arguments.

26 Aug 2022 1:30 #29301

Paul, The gfortran gave diagnostics

    4 | call sub1

      |         1

Error: Explicit interface required for ‘sub1’ at (1): optional argument

exactly opposite to what i claim. It just formally follows the Standard which for safety always (as if there were two separate files while there were actually single file with two programs enough to think a bit further) requires interface but my point was that in some cases interface is not needed and smart compiler can deal with this rising its artificial intelligence to the next level and resolving the problem by itself. Smart compiler will be more verbose and will issues just the warning where tell the user all these suggestions Ken have shown above (place arguments in the MODULE or CONTAIN) for the user to be aware and decide what's to do. For my demo example where all a and b were defined it also should just issue a warning and go without a bug.

The FTN95 was as always smarter but just had a bug which needs fixing. Compared to FTN95 the gFortran just got more 2003/2008 features and has little bit better C integration and Intel Fortran compatibility (plus it supports OpenMP and MPI and could be sometimes faster) but as a bug crusher it is a disaster. It can sometimes swallow without hiccups such horrible mistakes in the source code that you can not believe. I will find such examples when time permits

26 Aug 2022 5:47 #29303

Dan

I don't understand what you are saying.

  1. Interfaces were introduced in Fortran 90.
  2. Fortran compilers support Fortran 77.
  3. For some features of Fortran 90, compilation requires an interface and both logic and the Standard naturally insist on this.

The sample program illustrates a case where FTN95 could give useful feedback but the bug is in the code not in the compiler. FTN95 is usually what you call 'smart' in situations like this but (at the moment) not in this particular case.

26 Aug 2022 9:07 #29304

Paul,

So that's 'smartish'.

Smart enough for me, though.

Eddie

26 Aug 2022 10:01 #29305

Paul, I'm trying to say that code does not complain if i define a and b in the module, it does not complain when i define a and b in CONTAINS like Ken revealed, but when i define a and b directly just one line before calling sub1(a=b) the compiler abruptly remembers the Standard and tells me that i forgot damn interface. Sounds kind of unusual, right? And the resolution i proposed is that despite asking for the interface is formally correct according to Standard but by the common sense compiler has to violate Standard and do not ask for interface just warning that in other circumstances in similar situations here could be an error (when two programs are in separate files). In my case with sub1(a=b) exactly there is no error in any circumstances as a and b are fully defined.

That how smart compiler should do. And FTN95 in many cases doing like that checking arguments of subroutines on match and mismatch. Can it do that at compile time instead of run time with /checkmate? Ideally it should. Computers are not yet perfect but the humans are even worse. Analyzing not only my mistakes in my own codes but even driving mistakes recently made on 3000 miles trip i am sure Elon Masks self-driving software would not make any of my mistakes when i barely escaped collision or wrong turns 😃. It would do its own mistakes if i'll fall asleep but this is different story

Please login to reply.