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.
I understand your initial scepticism about pointers in Fortran, especially if you’re comparing them to their functionality in C. However, I assure you that pointers in Fortran are powerful and versatile in their own right. While it’s true that their use in linked lists is one common application, they have many other uses, which I’ll outline below:
- Array sections: Fortran pointers can be used to create array sections, enabling you to work with subarrays without the need for copying data. This can lead to more efficient code. Edit: Use
associate
instead, see below. - Abstract data types: Pointers are essential in creating user-defined data types, such as trees and graphs. They enable you to create complex structures that can be easily manipulated and traversed.
- Interfacing with C: Since pointers are a fundamental concept in C, using them in Fortran can facilitate the integration of Fortran code with C libraries and programs.
As you can see, pointers in Fortran are not just limited to linked lists but offer a wide range of functionality that can greatly improve the efficiency and readability of your code. So, I encourage you to explore pointers further and discover the many benefits they can bring to your Fortran programming experience.
When working with pointers, it’s crucial to keep in mind their potential pitfalls, such as dangling pointers, memory leaks, and segmentation faults. These issues can lead to unpredictable behaviour, crashes, or security vulnerabilities in your program. If you choose to use pointers, ensure that you understand their risks and follow best practices for pointer management, such as proper allocation, deallocation, and initialization.
In summary, while pointers can be a valuable tool in Fortran, it’s essential to carefully consider whether their use is necessary for your specific programming task. In numerous instances, safer and more straightforward alternatives exist that can help you achieve your goals while minimizing the potential for errors and complications.
ASSOCIATE is now recommended for this, as discussed here, where @sblionel wrote
Use of POINTER definitely can hurt optimization.
Thank you for pointing that out.
Are there still any use cases for pointers in this particular context?
Anyway, associate
is highly underrated. Do you know any good literature about this remarkable feature?
This is also not exactly true. One can use allocatable
much of the time here, a la:
class(abstract_base_t), allocatable :: var
In fortran, there are several safer and more robust alternatives to pointers. One can define, for example, linked lists (and other tree and network data structures) with allocatables rather than pointers. Also mentioned already, ASSOCIATE can replace many uses of pointers for array slices. The intrinsic MOVE_ALLOC() can be used in many situations to avoid pointer assignments, to perform shallow copy operations, etc. As a general rule, I try to avoid pointers as much as possible in fortran. Even when I do need to use them, it is often in combination with allocatables, so I can retain and exploit their nice features.
Are procedure pointers
included in this would-rather-not-use category?
Procedure pointers can be kinda seen as facilitating the use of an EXTERNAL
subprogram but with the possibility of an explicit interface. Wherever EXTERNAL
is recognized as needed, procedure pointers can be a better replacement.
The only alternatives to procedure pointers are dummy subprogram arguments and contained (type bound) procedures. I do sometimes use those rather than procedure pointers.
I see your point when building a single linked list or a simple tree. But what if I want to create a double linked list, a tree with pointers to the parents, or general graphs? Can I simply store the references in nodes?
Fortran “as it was in the beginning” was nice and transparent. Why was there a need for mind boggling obfuscation?
It is easier to write nice and transparent code in Fortran 90 and beyond than in earlier versions of the language. Your question is too broad to answer. The rationale for specific features can be discussed.
Pointers can be very handy, but they have to be treated with caution!
Here is an use case in which using pointers I managed to have a compact user interface for string to number conversion yet maintaining the performance of the code. The two main reasons for using the pointer interface were that (1) in the str2num conversion using indexing with integer(1) values helped in the performance, (2) stream lining through a long chain can be easily done by simply shifting the pointer instead of juggling with indexes.
I also agree with @FortranFan, I do prefer using procedure pointers rather than EXTERNAL procedures.
It is not a black-&-white matter, more of a “it depends”, and one should always ponder between how many lines of code are saved against the possible pitfalls of mangling with pointers.
You can for instance manage flexible type bound data containers with pointers:
type :: mytype
logical :: imowner = .false.
real, pointer :: x(:) => null()
end type
Will enable you to either allocate the data in ‘x’ or just use it as temporal working pointer. One has to be careful when destroying the object on whether one did actually allocate it or just point to something else. If this is done properly, the end user interfaces can be really clean and powerful.
Indeed, for those cases one would need pointers, in at least one direction. Note I said
However, you could still make use of allocatable for one direction of association to get the automatic memory management and not have to manually deallocate all nodes. I also find I don’t need the extra complication of doubly linked lists or doubly linked trees very often (if at all), but maybe that’s just me.
The piece of code I was thinking about is some math/numerical computations, where the solution algorithm can be one of many. The user can choose said method, and somewhere during the program there is a select case
based on the user-input argument.
Code is something like:
! set up data
! associate procedure pointer fun
do
! some math
call fun(...)
! math
! possibly call fun again
if (converge) exit
end do
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.
The integer on which the select case
is based, does not change, so perhaps it would not affect performance even though the loop may be run thousands of times.
Is a type-bound procedure
that different from a procedure pointer
, compiler implementation-wise?
I’ve followed the link and read the topic, only to find @sblionel’s explanations sort of self-contradictory:
ASSOCIATE has no relationship at all with POINTER.
You could, I suppose, think of it [i.e. ASSOCIATE construct] as a limited-scope POINTER that has type and shape and that comes into existence when the construct is entered and disappears on exit.
Could the author (or anybody) comment on that?
There is the computer science concept of pointers and there is the POINTER
facility in the Fortran language with its own semantics and syntax. The two are not identical by any means, the latter leans far more toward an alias to an object:
- you can view
ASSOCIATE
as having “no relationship at all” with the latter i.e., with thePOINTER
attributed objects, there is a concept of association that can be queried with an intrinsicIS_ASSOCIATED
but not so with anassociate-name
. - Also, an object with the
POINTER
attribute can only associated with a validTARGET
and the language has certain semantics as to what is a valid target, - On the other hand, there is some commonality with the
associate-name
in an ASSOCIATE construct and the constant pointer reference in computer science. - Moreover, in the
associate-name => selector
association in anASSOCIATE
construct, the selector has requirements different from those of a validTARGET
.
So there it is … some parallels with some computer science aspects that are heavily influenced by C and other languages but with some quirks and intricacies of Fortran itself!
Sorry if I rambled too much.
ASSOCIATE is indeed not POINTER. Nor, as some Intel developers first thought, is it a form of macro. ASSOCIATE creates a new entity that has some properties of the selector and shares the same storage.
I’m still learning how to use ASSOCIATE blocks, but my mental picture is that A=>B is like a dummy argument association in an internal procedure, except that there is no subroutine call, it is done inline in what would be the calling subprogram. A does not need to be declared and B need not be a target.
Re: “A does not need to be declared”, yes indeed - there is autotyping that comes into play with ASSOCIATE
which doesn’t with internal procedures and with POINTER
↔ TARGET
association. This is what many coders will find productive with ASSOCIATE
constructs.