# Nested function calls in Fortran?

**URL:** https://fortran-lang.discourse.group/t/nested-function-calls-in-fortran/994
**Category:** Uncategorized
**Created:** [April 8, 2021, 7:40am UTC](https://fortran-lang.discourse.group/t/nested-function-calls-in-fortran/994 "2021-04-08T07:40:36Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![rdryne](https://avatars.discourse-cdn.com/v4/letter/r/35a633/32.png) [@rdryne](https://fortran-lang.discourse.group/u/rdryne)
#### Post date: [April 8, 2021, 7:40am UTC](https://fortran-lang.discourse.group/t/nested-function-calls-in-fortran/994/1 "2021-04-08T07:40:36Z")

</div>

I’m writing a program that involves the Baker-Campbell-Hausdorff series. Suppose that I want to evaluate expressions with multiple nested commutators. (My actual application involves multiple nested Poisson brackets of 1D arrays, but it’s the same idea.) Suppose I’ve written a function cmt(a,b) that takes two matrices as input and returns their commutator,

cmt(a,b) = matmul(a,b) - matmul(b,a)

I need to evaluate very long expressions produced by Mathematica that look like,

e=cmt(a,b) + cmt(a,cmt(b,c))/3. - cmt(cmt(a,b),cmt(c,d))/10.

Is this acceptable in Fortran? gfortran doesn’t complain, but I’m getting strange results. I’m not sure if I’ve made a coding error or if this is non-standard Fortran. Is it legitimate for the actual argument in a function call (i.e., a user-supplied function, not an intrinsic) to contain the same function name?

---

<div class="post-metadata">

### Author: ![vmagnin](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/vmagnin/32/28_2.png) [@vmagnin](https://fortran-lang.discourse.group/u/vmagnin)
#### Post date: [April 8, 2021, 7:54am UTC](https://fortran-lang.discourse.group/t/nested-function-calls-in-fortran/994/2 "2021-04-08T07:54:50Z")

</div>

> [@rdryne](#):
>
> Is it legitimate for the actual argument in a function call (i.e., a user-supplied function, not an intrinsic) to contain the same function name?

No problem. The function call is replaced by the returned result, and so on.

Can you post more details about the problem? And more code?

---

<div class="post-metadata">

### Author: ![alozada](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/alozada/32/298_2.png) [@alozada](https://fortran-lang.discourse.group/u/alozada)
#### Post date: [April 8, 2021, 11:06am UTC](https://fortran-lang.discourse.group/t/nested-function-calls-in-fortran/994/3 "2021-04-08T11:06:55Z")

</div>

> [@rdryne](#):
>
> involves multiple nested Poisson brackets of 1D arrays

Maybe this can be useful,

```auto
program main
  use iso_fortran_env, only: wp => real64

  implicit none

  integer, parameter :: n=4
  real(kind=wp) :: R(n), s(n), T(n), U(n)
  real(kind=wp) :: W(n,n)

  R = [1.0, 2.0, 3.0, 4.0]
  S = [1.0, 2.0, 3.0, 4.0]
  T = [1.0, 2.0, 3.0, 4.0]
  U = [1.0, 2.0, 3.0, 4.0]

  write(*,*) '[R,S]'
  W = cmt(R,S)
  write(*,'(4f10.1)') W

  write(*,*) '[R,S] + [R,[R,S]]'
  W = cmt(R,S) + cmt(R,cmt(R,S))
  write(*,'(4f10.1)') W

  write(*,*) '[R,S] + [R,[R,S]]/3'
  W = cmt(R,S) + (cmt(R,cmt(R,S))/3.0)
  write(*,'(4f10.1)') W

  write(*,*) '[R,S] + [R,[R,S]]/3 - [[R,S],[T,U]]/10'
  W = cmt(R,S) + (cmt(R,cmt(R,S))/3.0) - (cmt(cmt(R,S),cmt(T,U))/10.0)
  write(*,'(4f10.1)') W

contains

  function cmt(A, B) result(C)
    real(wp), intent(in) :: A(n), B(n)
    real(wp) :: D(n,1), E(1,n)
    real(wp) :: C(n,n)

    D = reshape(A,(/n,1/))
    E = reshape(B,(/1,n/))

    C = matmul(D,E)

  end function cmt
end program main

```

![results](https://global.discourse-cdn.com/free1/uploads/fortran_lang/original/1X/ad0f7bb47ce799dd21276a8da1e2851174b4d9d2.png)

---

<div class="post-metadata">

### Author: ![rdryne](https://avatars.discourse-cdn.com/v4/letter/r/35a633/32.png) [@rdryne](https://fortran-lang.discourse.group/u/rdryne)
#### Post date: [April 12, 2021, 3:03am UTC](https://fortran-lang.discourse.group/t/nested-function-calls-in-fortran/994/4 "2021-04-12T03:03:11Z")

</div>

Thanks for these replies. I have been debugging on-and-off for the past couple of days. I mentioned that I had been seeing some strange results – the code did not give the correct result for a certain test problem. After doing some editing I began to get segmentation faults. And it was the frustrating kind of segfault where you can put diagnostics at the beginning of subroutines and the code seems to crash upon entry (without even print hello from subroutine blah) for no good reason. There is some legacy code mixed in with this so I spent a lot of time seeing if something in the legacy code might be trashing memory.

In the end it appears that all my problems go away when I take a very long statement – one with 66 continuation lines – and break it into several smaller statements. I am really surprised by this. Has anyone else here experienced this type of situation?

---

<div class="post-metadata">

### Author: ![vmagnin](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/vmagnin/32/28_2.png) [@vmagnin](https://fortran-lang.discourse.group/u/vmagnin)
#### Post date: [April 12, 2021, 8:45am UTC](https://fortran-lang.discourse.group/t/nested-function-calls-in-fortran/994/5 "2021-04-12T08:45:25Z")

</div>

> [@rdryne](#):
>
> In the end it appears that all my problems go away when I take a very long statement – one with 66 continuation lines – and break it into several smaller statements. I am really surprised by this. Has anyone else here experienced this type of situation?

As far I as know, there was 39 continuation lines allowed before Fortran 2003. And since Fortran 2003 it is 255.

---

<div class="post-metadata">

### Author: ![rdryne](https://avatars.discourse-cdn.com/v4/letter/r/35a633/32.png) [@rdryne](https://fortran-lang.discourse.group/u/rdryne)
#### Post date: [April 12, 2021, 7:14pm UTC](https://fortran-lang.discourse.group/t/nested-function-calls-in-fortran/994/6 "2021-04-12T19:14:59Z")

</div>

The problem with too many continuation lines causing a segfault was happening on my MacBook (MacOS Sierra) with an old version of gfortran:  
gfortran --version  
GNU Fortran (Homebrew GCC 7.2.0) 7.2.0

So I moved the code to another platform and tried it with 3 different compilers: Cray, Intel, and gfortran 8.3.0 . There was no problem in those 3 cases.

So the problem appears to be due to using an old version of gfortran on my Mac.

---

<div class="post-metadata">

### Author: ![vmagnin](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/vmagnin/32/28_2.png) [@vmagnin](https://fortran-lang.discourse.group/u/vmagnin)
#### Post date: [April 12, 2021, 7:20pm UTC](https://fortran-lang.discourse.group/t/nested-function-calls-in-fortran/994/7 "2021-04-12T19:20:12Z")

</div>

> [@rdryne](#):
>
> So the problem appears to be due to using an old version of gfortran on my Mac.

And if you use `gfortran -std=f95` it should also cause an error.

---

<div class="post-metadata">

### Author: ![rdryne](https://avatars.discourse-cdn.com/v4/letter/r/35a633/32.png) [@rdryne](https://fortran-lang.discourse.group/u/rdryne)
#### Post date: [April 12, 2021, 7:42pm UTC](https://fortran-lang.discourse.group/t/nested-function-calls-in-fortran/994/8 "2021-04-12T19:42:31Z")

</div>

There are hundreds of compiler errors when I use -std=f95 because of the use of :: in declarations, etc. So I’m not able to try it with that compiler option.

---

<div class="post-metadata">

### Author: ![Beliavsky](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Beliavsky](https://fortran-lang.discourse.group/u/Beliavsky)
#### Post date: [April 12, 2021, 10:41pm UTC](https://fortran-lang.discourse.group/t/nested-function-calls-in-fortran/994/9 "2021-04-12T22:41:51Z")

</div>

> [@rdryne](#):
>
> There are hundreds of compiler errors when I use -std=f95 because of the use of :: in declarations, etc. So I’m not able to try it with that compiler option.

I wonder what declarations with `::` are disallowed by -std=f95. Certainly Fortran 95 and 90 have the `::` syntax, but is there a special case that only F2003+ allows?

---

<div class="post-metadata">

### Author: ![rdryne](https://avatars.discourse-cdn.com/v4/letter/r/35a633/32.png) [@rdryne](https://fortran-lang.discourse.group/u/rdryne)
#### Post date: [April 13, 2021, 1:51am UTC](https://fortran-lang.discourse.group/t/nested-function-calls-in-fortran/994/10 "2021-04-13T01:51:13Z")

</div>

Here are some examples of the compiler diagnostics:

```
   real*8 function mzran()
        1

```

Error: GNU Extension: Nonstandard type declaration REAL\*8 at (1)  
and

```
   integer :: i,k,ip,kp
                      1

```

Error: Unexpected data declaration statement at (1)

and

```
   integer :: n
              1

```

Error: Unexpected data declaration statement at (1)

and

```
   real*8, dimension(monoms) :: f3,f4,f5,f6,f7,f8,tmp,tmp2,tmp3,tmp4,tmp5,tmp6
        1

```

Error: GNU Extension: Nonstandard type declaration REAL\*8 at (1)

and

```
   g5(210:461)=g(210:461)
  1

```

Error: Unclassifiable statement at (1)

The list of compiler complaints goes on and on. Since this is a bit off topic I decided to move on. The main thing, from my standpoint, is that now if I compile the code with Intel, Cray, or Gnu compilers (Gnu being a recent version and not the old version I was using on my Mac), it compiles fine and executes correctly.

---

<div class="post-metadata">

### Author: ![vmagnin](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/vmagnin/32/28_2.png) [@vmagnin](https://fortran-lang.discourse.group/u/vmagnin)
#### Post date: [April 13, 2021, 8:04am UTC](https://fortran-lang.discourse.group/t/nested-function-calls-in-fortran/994/11 "2021-04-13T08:04:58Z")

</div>

> [@rdryne](#):
>
> Error: GNU Extension: Nonstandard type declaration REAL\*8 at (1)

Yes, `*8` is non standard, although a classical extension. `REAL(8)` or `REAL(kind=8)` is standard, but read that post for still better solutions:

> [@Best way to declare a double precision in Fortran?](https://fortran-lang.discourse.group/t/best-way-to-declare-a-double-precision-in-fortran/69):
>
> Hi, there is several ways to declare a double precision real in Fortran: real\*8 :: w real(8) :: x real(kind(0d0)) :: y double precision :: z My habits are to use double precision. Is it a good practice ?

---

<div class="post-metadata">

### Author: ![rdryne](https://avatars.discourse-cdn.com/v4/letter/r/35a633/32.png) [@rdryne](https://fortran-lang.discourse.group/u/rdryne)
#### Post date: [April 14, 2021, 6:26pm UTC](https://fortran-lang.discourse.group/t/nested-function-calls-in-fortran/994/12 "2021-04-14T18:26:37Z")

</div>

Thank you for pointing me to the “Best way to declare a double…” thread. I read it and the “It takes all kinds” article mentioned within it. As I move forward I would like to write code that adheres to the Fortran standard, and those discussions were very helpful.

---

<div class="post-metadata">

### Author: ![vmagnin](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/vmagnin/32/28_2.png) [@vmagnin](https://fortran-lang.discourse.group/u/vmagnin)
#### Post date: [April 14, 2021, 6:32pm UTC](https://fortran-lang.discourse.group/t/nested-function-calls-in-fortran/994/13 "2021-04-14T18:32:02Z")

</div>

Personally, I have improved my practice by using:

```auto
use, intrinsic :: iso_fortran_env, only: wp=>real64
implicit none
real(wp) :: alpha

```
