# Pointers / Free Literature on Fortran

**URL:** https://fortran-lang.discourse.group/t/pointers-free-literature-on-fortran/5597
**Category:** Uncategorized
**Created:** [April 18, 2023, 12:33pm UTC](https://fortran-lang.discourse.group/t/pointers-free-literature-on-fortran/5597 "2023-04-18T12:33:47Z")
**Posts on this page:** 18
**Page:** 2

<div class="post-metadata">

### Author: ![hkvzjal](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/hkvzjal/32/3055_2.png) [@hkvzjal](https://fortran-lang.discourse.group/u/hkvzjal)
#### Post date: [April 20, 2023, 7:42am UTC](https://fortran-lang.discourse.group/t/pointers-free-literature-on-fortran/5597/22 "2023-04-20T07:42:51Z")

</div>

There are a couple of use cases in which I like using ASSOCIATE:

1. Pure aesthetics and easier-to-read code:

Lets say that one has an intricated derived type (more than 3 levels of indirection), it is then quite nice to have an ASSOCIATE wrapping the actual implementation of the method to facilitate the mental picture of what is happening

imaging handling a mesh with coordinates and connectivities in such a way:

```auto
associate( X=>mytype%list_objects(index)%coordinates , &
        & connectivity=>mytype%list_objects(index)%connectivity )
! here work with X(:,:) and connectivity(:,:)
end associate

```

1. Data buffers recycling

Lets say that one would like to allocate just once a buffer to then work with small batches of data to avoid reallocations …  
you could do something like

```auto
real, allocatable :: data(:)
...
allocate( data(big_size) )
...
associate( variable1 => data(1) , variable2 => data(2:5) )
! do something with variable1 & variable2 
end associate
.. ! later on in the same scope
associate( variable3 => data(1:10) , variable4 => data(11) )
! do something with variable3 & variable4
end associate

```

No data copied, no risks with pointers being nullified with the data hanging somewhere, and no need of declaration at the header.

---

<div class="post-metadata">

### Author: ![Patrick](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/patrick/32/3170_2.png) [@Patrick](https://fortran-lang.discourse.group/u/Patrick)
#### Post date: [April 20, 2023, 2:00pm UTC](https://fortran-lang.discourse.group/t/pointers-free-literature-on-fortran/5597/23 "2023-04-20T14:00:24Z")

</div>

hkvzjal, thank you very much for your information re “associate”. I shall study what you wrote with great interest. Patrick.

---

<div class="post-metadata">

### Author: ![ivanpribec](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ivanpribec/32/3290_2.png) [@ivanpribec](https://fortran-lang.discourse.group/u/ivanpribec)
#### Post date: [April 20, 2023, 9:53pm UTC](https://fortran-lang.discourse.group/t/pointers-free-literature-on-fortran/5597/24 "2023-04-20T21:53:58Z")

</div>

> [@Patrick](#):
>
> Fortran “as it was in the beginning” was nice and transparent. Why was there a need for mind boggling obfuscation?

The language is mostly backward compatible. If you don’t like modern features, you don’t need to use them. Take for example this minimization procedure by [Richard Brent](https://maths-people.anu.edu.au/~brent/) extracted from Algorithms for Minimization Without Derivatives, published in 1973:

> **localmin**
>
> ```fortran
> C A FORTRAN TRANSLATION OF THE ALGOL PROCEDURE LOCALMIN.
> C SEE PROCEDURE LOCALMIN, SECTION 5.8, FOR COMMENTS ETC.
> REAL FUNCTION LOCALM(A, B, EPS, T, F, X)
> REAL A,B,EPS,T,F,X,SA,SB,D,E,M,P,Q,R,TOL,T2,U,V,W,FU,FV,FW,FX
> SA = A
> SB = B
> X = SA + 0.381966*(SB - SA)
> W = X
> V = W
> E = 0.0
> FX = F(X)
> FW = FX
> FV = FW
> 10 M = 0.5*(SA + SB)
> TOL = EPS*ABS(X) + T
> T2 = 2.0*TOL
> IF (ABS(X-M).LE.T2-0.5*(SB-SA)) GO TO 190
> R = 0.0
> Q = R
> P = Q
> IF (ABS(E).LE.TOL) GO TO 40
> R = (X - W)*(FX - FV)
> Q = (X - V)*(FX - FW)
> P = (X - V)*Q - (X - W)*R
> Q = 2.0*(Q - R)
> IF (Q.LE.0.0) GO TO 20
> P = -P
> GO TO 30
> 20 Q = -Q
> 30 R = E
> E = D
> 40 IF (ABS(P).GE.ABS(0.5*Q*R)) GO TO 60
> IF ((P.LE.Q*(SA-X)).OR.(P.GE.Q*(SB-X))) GO TO 60
> D = P/Q
> U = X + D
> IF ((U-SA.GE.T2).AND.(SB-U.GE.T2)) GO TO 90
> IF (X.GE.M) GO TO 50
> D = TOL
> GO TO 90
> 50 D = -TOL
> GO TO 90
> 60 IF (X.GE.M) GO TO 70
> E = SB - X
> GO TO 80
> 70 E = SA - X
> 80 D = 0.381966*E
> 90 IF(ABS(D).LT.TOL) GO TO 100
> U = X + D 
> GO TO 120
> 100 IF (D.LE.0.0) GO TO 110
> U = X + TOL
> GO TO 120
> 110 U = X - TOL
> 120 FU = F(U)
> IF (FU.GT.FX) GO TO 150
> IF (U.GE.X) GO TO 130
> SB = X
> GO TO 140
> 130 SA = X
> 140 V = W
> FV = FW
> W = X
> FW = FX
> X = U
> FX = FU
> GO TO 10
> 150 IF (U.GE.X) GO TO 160
> SA = U
> GO TO 170
> 160 SB = U
> 170 IF ((FU.GT.FW).AND.(W.NE.X)) GO TO 180
> V = W
> FV = FW
> W = U
> FW = FU
> GO TO 10
> 180 IF ((FU.GT.FV).AND.(V.NE.X).AND.(V.NE.W)) GO TO 10
> V = U
> FV = FU
> GO TO 10 
> 190 LOCALM = FX
> RETURN
> END
> 
> ```

(Variations of the routine appear under the name `fmin` in the [“golden oldies”](https://netlib.org/go/index.html) folder on Netlib.)

It was written for a 1966 IBM machine, but it still compiles just fine today:

```txt
ivan:~/fortran$ gfortran -Wall -c -std=f2018 localm.f 
ivan:~/fortran$ 

```

If you feel that the language is complex, you can reduce the complexity _intentionally_ through self-restraint. (Similar to how monks practice asceticism.)

---

<div class="post-metadata">

### Author: ![ivanpribec](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ivanpribec/32/3290_2.png) [@ivanpribec](https://fortran-lang.discourse.group/u/ivanpribec)
#### Post date: [April 20, 2023, 10:35pm UTC](https://fortran-lang.discourse.group/t/pointers-free-literature-on-fortran/5597/25 "2023-04-20T22:35:16Z")

</div>

One use of pointers which hasn’t been mentioned yet is bounds-remapping, e.g.

```fortran
real, target :: a(2,3)
real, pointer :: aflat(:)
aflat(1:6) => a

```

This can be useful to temporarily modify the rank of an array, or use custom bounds. While this may inhibit optimization in some cases, it can help avoid copies in others. In case you know for certain there is no aliasing, you can help the compiler by passing the pointer array as a dummy argument.

> [@Robpk](#):
>
> A `procedure pointer` was chosen, for simplicity, perhaps (and cleaner code). The `select case` has 20+ `case` statements. So instead of having a huge `case` there in the middle of the `do` loop, it is done once outside the loop.

With Fortran 2003, you don’t even need a select case construct, but you can use an array to make a dispatch table:

```fortran
! foo.f90
module foo
implicit none
abstract interface
   subroutine void()
   end subroutine
end interface
contains
   subroutine a()
      print *, "Foo"
   end subroutine
   subroutine b()
      print *, "Bar"
   end subroutine
   subroutine c()
      print *, "Baz"
   end subroutine
end module
program main
use foo, only: void, a, b, c
implicit none
type :: pp
   procedure(void), pointer, nopass :: pf => null()
end type
type(pp) :: table(3)
integer ::i
table = [pp(a),pp(b),pp(c)]
do i = 1, 3
   call table(i)%pf()
end do
end program

```

The NAG Fortran compiler already supports default initialisation of procedure pointer components:

```fortran
type(pp), parameter :: table(3) = [pp(a),pp(b),pp(c)]

```

Due to the additional derived type needed, the syntax is a bit more verbose when compared to C:

```c
#include <stdio.h>
void a(void) { puts("foo"); }
void b(void) { puts("bar"); }
void c(void) { puts("baz"); }
typedef void (*pp)(void);
static const pp table[] = { a, b, c };
int main(void)
{
  for (int i = 0; i < 3; ++i) 
    table[i]();
  return 0;
}

```

I was interested recently, in comparing `select case` and computed `goto`, vs a procedure pointer dispatch table. You can look at here on compiler explorer: [Compiler Explorer](https://godbolt.org/z/e8P8P67xE). The outcome was both generate very similar machine instructions. For the procedure pointer solution, `gfortran` just unrolled the whole loop:

```txt
        call __foo_MOD_a
        call [QWORD PTR table.0[rip+8]]
        call [QWORD PTR table.0[rip+16]]

```

---

<div class="post-metadata">

### Author: ![PierU](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/pieru/32/1848_2.png) [@PierU](https://fortran-lang.discourse.group/u/PierU)
#### Post date: [April 20, 2023, 10:39pm UTC](https://fortran-lang.discourse.group/t/pointers-free-literature-on-fortran/5597/26 "2023-04-20T22:39:02Z")

</div>

> [@Patrick](#):
>
> I find pointers in conjunction with linked lists in the literature (Fortran 90/95, Programming Manual by Tanja Mourik: free, excellent and downloadable). I see no other application of pointers. Is the use of pointers in Fortran that limited? Pointers are very useful in C.

As stated by other contributors, modern Fortran has often high level alternatives to pointers, that C does not offer (C++ is another story). Also, keep in mind that Fortran pointers are fairly different from C pointers.

When pointers were introduced in Fortran 90 there were more usage cases for pointers than there are now. For instance in the recent versions of the standard allocatable objects are allowed in derived types or as dummy arguments, which was not the case in F90, so pointers had to be used instead.

---

<div class="post-metadata">

### Author: ![FortranFan](https://avatars.discourse-cdn.com/v4/letter/f/96bed5/32.png) [@FortranFan](https://fortran-lang.discourse.group/u/FortranFan)
#### Post date: [April 20, 2023, 11:19pm UTC](https://fortran-lang.discourse.group/t/pointers-free-literature-on-fortran/5597/27 "2023-04-20T23:19:12Z")

</div>

> [@ivanpribec](#):
>
> … With Fortran 2018, you don’t even need a select case construct, but you can use an array to make a dispatch table …

You mean “starting with Fortran 2003”? Your shown example conforms with Fortran 2003.

---

<div class="post-metadata">

### Author: ![ivanpribec](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ivanpribec/32/3290_2.png) [@ivanpribec](https://fortran-lang.discourse.group/u/ivanpribec)
#### Post date: [April 20, 2023, 11:21pm UTC](https://fortran-lang.discourse.group/t/pointers-free-literature-on-fortran/5597/28 "2023-04-20T23:21:12Z")

</div>

> [@Patrick](#):
>
> Pointers are very useful in C.

Quoting [Rob Pike](http://doc.cat-v.org/bell_labs/pikestyle) (co-creator of UTF-8 and also the Go programming language):

> Pointers are sharp tools, and like any such tool, used well they can be delightfully productive, but used badly they can do great damage (I sunk a wood chisel into my thumb a few days before writing this).

While pointers can be very elegant when used correctly, the NSA and US Department of Commerce sent the C/C++ world into panic, when they published an [information sheet on memory safety](https://media.defense.gov/2022/Nov/10/2003112742/-1/-1/0/CSI_SOFTWARE_MEMORY_SAFETY.PDF), in light of the increased amount of cyber attacks. Here are some popular articles on the topic:

- [NSA urges orgs to use memory-safe programming languages](https://www.theregister.com/2022/11/11/nsa_urges_orgs_to_use/)
- [Programming languages: It’s time to stop using C and C++ for new projects, says Microsoft Azure CTO](https://www.zdnet.com/article/programming-languages-its-time-to-stop-using-c-and-c-for-new-projects-says-microsoft-azure-cto/)
- [Can C++ Be Saved? Bjarne Stroustrup on Ensuring Memory Safety](https://thenewstack.io/can-c-be-saved-bjarne-stroustrup-on-ensuring-memory-safety/)

In the 2022 list of [Top 25 most dangerous software weaknesses](https://cwe.mitre.org/top25/archive/2022/2022_cwe_top25.html), you have 5 related to memory safety, the #1 weakness being out-of-bounds write. Some of the C/C++ colleagues I work with, won’t even look at my code unless I’ve ran it through a [code sanitizer](https://en.wikipedia.org/wiki/Code_sanitizer) such as [LSan](https://clang.llvm.org/docs/LeakSanitizer.html).

I used to think the attack threat is blown out of proportion, but a few weeks ago, a scientific research institute in Munich was [left completely paralyzed](https://b2b-cyber-security.de/en/cyberattacke-auf-helmholtz-zentrum-muenchen/) as a result of one.

IMO, Fortran pointers with the target concept were ahead of their time, judging by the repercussions we see today for C/C++.

---

<div class="post-metadata">

### Author: ![ivanpribec](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ivanpribec/32/3290_2.png) [@ivanpribec](https://fortran-lang.discourse.group/u/ivanpribec)
#### Post date: [April 20, 2023, 11:23pm UTC](https://fortran-lang.discourse.group/t/pointers-free-literature-on-fortran/5597/29 "2023-04-20T23:23:01Z")

</div>

Thanks for the correction. (I’ve verified that the example compiles successfully with `gfortran` and the flag `-std=f2003`)

Does that apply also to the default initialization?

```fortran
type(pp), parameter :: table(3) = [pp(a),pp(b),pp(c)]

```

---

<div class="post-metadata">

### Author: ![FortranFan](https://avatars.discourse-cdn.com/v4/letter/f/96bed5/32.png) [@FortranFan](https://fortran-lang.discourse.group/u/FortranFan)
#### Post date: [April 20, 2023, 11:45pm UTC](https://fortran-lang.discourse.group/t/pointers-free-literature-on-fortran/5597/30 "2023-04-20T23:45:09Z")

</div>

> [@ivanpribec](#):
>
> . Does that apply also to the default initialization?

Great question, I think so, that it conforms to Fortran 2003 but I’m not 100% sure. Both Intel Fortran and gfortran don’t support the named constant declaration.

With NAG Fortran, is it possible to do standards checking similar to `-std=` with GCC?

---

<div class="post-metadata">

### Author: ![ivanpribec](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ivanpribec/32/3290_2.png) [@ivanpribec](https://fortran-lang.discourse.group/u/ivanpribec)
#### Post date: [April 21, 2023, 12:04am UTC](https://fortran-lang.discourse.group/t/pointers-free-literature-on-fortran/5597/31 "2023-04-21T00:04:12Z")

</div>

It is possible:

```plaintext
$ nagfor -f2018 foo.f90 
NAG Fortran Compiler Release 7.1(Hanzomon) Build 7101
[NAG Fortran Compiler normal termination]
$ nagfor -f2008 foo.f90 
NAG Fortran Compiler Release 7.1(Hanzomon) Build 7101
[NAG Fortran Compiler normal termination]
$ nagfor -f2003 foo.f90 
NAG Fortran Compiler Release 7.1(Hanzomon) Build 7101
Extension(F2008): foo.f90, line 24: Value A for procedure pointer component PF in PP structure constructor in constant expression is not a disassociated pointer
Extension(F2008): foo.f90, line 24: Value B for procedure pointer component PF in PP structure constructor in constant expression is not a disassociated pointer
Extension(F2008): foo.f90, line 24: Value C for procedure pointer component PF in PP structure constructor in constant expression is not a disassociated pointer
[NAG Fortran Compiler normal termination, 3 warnings]

```

---

<div class="post-metadata">

### Author: ![Aurelius\_Nero](https://avatars.discourse-cdn.com/v4/letter/a/a87d85/32.png) [@Aurelius\_Nero](https://fortran-lang.discourse.group/u/Aurelius_Nero)
#### Post date: [April 26, 2023, 6:55am UTC](https://fortran-lang.discourse.group/t/pointers-free-literature-on-fortran/5597/32 "2023-04-26T06:55:02Z")

</div>

Forgive my noobish question, but can `associate` be used to create things like linked lists ?

---

<div class="post-metadata">

### Author: ![Carltoffel](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/carltoffel/32/1680_2.png) [@Carltoffel](https://fortran-lang.discourse.group/u/Carltoffel)
#### Post date: [April 26, 2023, 9:19am UTC](https://fortran-lang.discourse.group/t/pointers-free-literature-on-fortran/5597/33 "2023-04-26T09:19:39Z")

</div>

I tried to implement a linked list without pointers, but it was more difficult than I thought. The only way I found to traverse the list and append something was by using recursive functions because they allow you to pass by reference.

`associate` doesn’t work as I expected. What’s the problem here?

```auto
associate(next => current_node%next)
    if(.not. allocated(next)) then
        allocate(next)
        next%data = data
    else
        call append_node(next, data) ! recursion
    end if
end associate

```

> **gfortran a.f90 -g**
>
> ```auto
> a.f90:29:25:
> 
> 29 | allocate(next)
> | 1
> Error: Allocate-object at (1) is neither a data pointer nor an allocatable variable
> a.f90:28:31:
> 
> 28 | if(.not. allocated(next)) then
> | 1
> Error: ‘array’ argument of ‘allocated’ intrinsic at (1) must be ALLOCATABLE
> 
> ```

Here is a functioning program:

> **Whole code**
>
> ```auto
> program linked_list
> implicit none
> 
> type node
> integer :: val
> type(node), allocatable :: next
> end type node
> 
> type(node) :: head, last
> integer :: i
> 
> head%val = 0
> 
> ! Add some nodes to the linked list
> do i=1,3
> call append_node(head, i)
> end do
> 
> last = get_last_node(head)
> print *, "last =", last%val
> 
> contains
> 
> recursive subroutine append_node(current_node, val)
> type(node), intent(inout) :: current_node
> integer, intent(in) :: val
> 
> if(.not. allocated(current_node%next)) then
> allocate(current_node%next)
> current_node%next%val = val
> else
> call append_node(current_node%next, val)
> end if
> end subroutine append_node
> 
> recursive function get_last_node(current_node) result(last_node)
> type(node), intent(in) :: current_node
> type(node) :: last_node
> 
> print *, "current =", current_node%val
> 
> if(.not. allocated(current_node%next)) then
> last_node = current_node
> else
> last_node = get_last_node(current_node%next)
> end if
> end function get_last_node
> 
> end program linked_list
> 
> ```

Does anyone has an idea how to make single linked list properly?

---

<div class="post-metadata">

### Author: ![han190](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/han190/32/7158_2.png) [@han190](https://fortran-lang.discourse.group/u/han190)
#### Post date: [April 26, 2023, 11:27am UTC](https://fortran-lang.discourse.group/t/pointers-free-literature-on-fortran/5597/34 "2023-04-26T11:27:49Z")

</div>

The standard says

```auto
19.5.1.6 Construct association
2 In an ASSOCIATE or SELECT TYPE construct, the following rules apply.
  • If a selector is allocatable, it shall be allocated; the associate name is 
    associated with the data object and does not have the ALLOCATABLE attribute.
  • If a selector has the POINTER attribute, it shall be associated; 
    the associate name is associated with the target of the pointer and 
    does not have the POINTER attribute.

```

so, technically if you `associate(next => current_node%next)` you are assuming it is already allocated and cannot be deallocated within the associate construct. Then, the `if(.not. allocated(next))` is probably a bit confusing.

---

<div class="post-metadata">

### Author: ![everythingfunctional](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/everythingfunctional/32/176_2.png) [@everythingfunctional](https://fortran-lang.discourse.group/u/everythingfunctional)
#### Post date: [April 26, 2023, 1:55pm UTC](https://fortran-lang.discourse.group/t/pointers-free-literature-on-fortran/5597/35 "2023-04-26T13:55:26Z")

</div>

I’d be tempted to report this as a bug to gfortran. As @han190 quoted

> [@han190](#):
>
> the associate name is associated with the data object and does not have the ALLOCATABLE attribute.

So gfortran should have flagged the use of the `allocated` intrinsic on an object that does not have the `allocatable` attribute as an error at compile time.

---

<div class="post-metadata">

### Author: ![hkvzjal](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/hkvzjal/32/3055_2.png) [@hkvzjal](https://fortran-lang.discourse.group/u/hkvzjal)
#### Post date: [April 26, 2023, 2:14pm UTC](https://fortran-lang.discourse.group/t/pointers-free-literature-on-fortran/5597/36 "2023-04-26T14:14:21Z")

</div>

ifort/ifx also would return a compile time error:

```auto
error #8306: Associate name defined in ASSOCIATE or SELECT TYPE statements doesn't have ALLOCATABLE or POINTER attribute. [NEXT]
            allocate(next)

```

I usually use associate for already allocated or pointing-to data, not for such dynamic creation precisely because of such kind of issues, and I don’t think it was designed to be used for such purposes … ?

---

<div class="post-metadata">

### Author: ![Carltoffel](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/carltoffel/32/1680_2.png) [@Carltoffel](https://fortran-lang.discourse.group/u/Carltoffel)
#### Post date: [April 26, 2023, 3:12pm UTC](https://fortran-lang.discourse.group/t/pointers-free-literature-on-fortran/5597/38 "2023-04-26T15:12:01Z")

</div>

Well, the error message is correct, but at least it is also misleading. If the error message said, that `next` is not allocatable **because** it is the nature of association, my error would be obvious.

---

<div class="post-metadata">

### Author: ![everythingfunctional](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/everythingfunctional/32/176_2.png) [@everythingfunctional](https://fortran-lang.discourse.group/u/everythingfunctional)
#### Post date: [April 26, 2023, 10:41pm UTC](https://fortran-lang.discourse.group/t/pointers-free-literature-on-fortran/5597/41 "2023-04-26T22:41:08Z")

</div>

Oops. My bad. The error message wasn’t mentioned so I didn’t think to look for it/at it. It could potentially be improved, but I don’t know how easy it would be. I don’t know if it knows why the object doesn’t have the allocatable attribute at the point it produces those errors.

---

<div class="post-metadata">

### Author: ![sblionel](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/sblionel/32/853_2.png) [@sblionel](https://fortran-lang.discourse.group/u/sblionel)
#### Post date: [April 28, 2023, 3:09pm UTC](https://fortran-lang.discourse.group/t/pointers-free-literature-on-fortran/5597/43 "2023-04-28T15:09:16Z")

</div>

FWIW, I do not recommend including standard section numbers in diagnostic messages, for two reasons:

1. Much effort will be required to update them for future revisions
2. The user is unlikely to have a copy of the standard handy, and even if they do, there can be multiple possibilities of violations.

I much prefer clearly worded, self-contained, and actionable diagnostic messages. I agree with @kargl that when there are multiple violations, the compiler will just report the first one found, which may still end up confusing the user.

[Previous page](https://fortran-lang.discourse.group/t/pointers-free-literature-on-fortran/5597.md?page=1)
