3

I just started using pointers in Fortran and recently stumbled upon the fact, that pointers in Fortran can't be constant. This means, something like this is not possible:

procedure(proc_type), pointer, parameter :: fPtr => myFunc

I tried to find out the reason why this is not possible. But the only thing I found was in "Modern Fortran explained":

Note also that a constant may not be a pointer [..] since these are always variables.

But this does not explain the reason behind that. Does anyone know about this?

3
  • Note that statement in MFE is out of date. Procedure pointers are not variables. Commented Oct 28, 2014 at 12:27
  • @IanH Can you elaborate a bit on this? Is there some more information about procedure pointers around? Commented Oct 28, 2014 at 13:37
  • There is a distinction between the everyday colloquial use of "variable" and the formal language definition (in the standard). In the formal sense, variables (and constants) are data objects. A procedure is not a data object. That section of MFE predates F2003 which introduced proc pointers, so I assumed that was just an oversight, but I see in the later section on proc pointers (13.6) they still call them variables, so perhaps they are using the colloquial sense. That's reasonable enough for a text book, but the distinction matters if you are going to discuss the details of the language. Commented Oct 28, 2014 at 14:08

3 Answers 3

6

Because the Fortran rules say so

Fortran 2008 (ISO/IEC 1539-1:2010):

5.3.14 POINTER attribute

1 Entities with the POINTER attribute can be associated with different data objects or procedures during execution of a program. A pointer is either a data pointer or a procedure pointer. Procedure pointers are described in 12.4.3.6.

This is not compatible with constants.

Why are the rules as this? Because the authors of the standard made it so.

Why they did it like that? The answer for this is very often very simple - because nobody presented a different rule to be discussed and approved by the committee, or that some members of the committee didn't like it. You really have to ask them - J3 and SC22/WG5, but be prepared to the answer that there is no specific reason for that.

In some languages which fall in the same category, e.g. C and C++, constant pointers are possible. A constant pointer initialized to point to an integer constant

const int i = 3;
static int* const x=(int*)&i;

A constant pointer initialized to point to an integer function

int fun(){
  return 1;
}

static int (* const x)()=&fun;

It would be definitely possible to allow something like that in Fortran. Contact your representative in the Fortran standards committee to suggest such a feature.

There are ways ti circumvent this restriction as shown by IanH and credondo, but this answers tries to stay i the line of the original question. Why this restriction exists?

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks. This confirms my suspicion that it is not due to technical reasons, e.g. the type system.
You can have static int* const in C and C++, so there could be easily something similar made up for Fortran.
I guess it will be more complicated when it comes to function pointers, right?
Again, static int (* const x)() is possible, so some equivalent could be proposed for Fortran. It would be technically possible.
1

If the pointer is declared within a module with the PROTECTED attribute, the pointer becomes constant (EDIT:) outside that module

module mod1
  implicit none
  procedure()                     :: p_target
  procedure(), pointer            :: ptr => null()
  procedure(), pointer, protected :: ptr_protected => null()
end module mod1


program pointer_parameter
  USE mod1
  implicit none
  ptr            => p_target        
  ptr_protected  => p_target
end program

The compiler returns the following error

gfortran -c pointer_parameter.f90
pointer_parameter.f90:6.3:

ptr_protected  => p_target
1
Error: Variable 'ptr_protected' is PROTECTED and can not appear in a pointer
association context (pointer assignment) at (1)

9 Comments

It does not become a constant. It cannot be changed outside of the module, but it can be changed inside of the module. It also can be changed using a pointer or similar tricks.
If the important reason for seeking a constant pointer is to inhibit other parts of the program from mutating its value then encapsulating it in a module is a step around the obstacle in the language specification. Short of changing the specification, one without full language support is the only sort of "constant pointer" a person can code up.
Unfortunately it is very easy to mutate it, is not a very strong protection. But more importantly, thy question asks why there is a restriction in the Fortran language and not how to circumvent it.
For procedure pointers @VladimirF comment "can be changed using a pointer or similar tricks" isn't relevant - pointers can only point at targets and not at other pointers, and you can't make the target of a procedure pointer go away within the bounds of the standard language. For pointers to data objects there is the possibility of deallocating the target (assuming it was initially created using allocate) through a different pointer or allocatable object, but the impact on the pointer association status of the protected pointer is very indirect in that case.
Then you have a nonconforming program. It is very simple to do something equivalent to that with an ordinary named constant too.
|
1

It depends on what you mean by a "constant pointer".

If you mean a pointer object whose association status cannot be changed during the execution of the program, then your premise is false... you can declare and initialize pointer objects whose association status cannot be changed during the execution of a program.

TYPE :: t
  PROCEDURE(xyz), POINTER :: fPtr
END TYPE t

TYPE(t), PARAMETER :: this_a_constant = t(myFunc)

Something similar is available for data objects. You can achieve a similar outcome using default initialization of the component.

If, in the case of pointers to data objects, you mean an object that points at a constant, then the immediate explanation is that named constants (and literal constants) in Fortran represent values, values cannot be targets and you can only associate pointers with targets. Behind that immediate explanation is the implementation perspective that the value may not actually need to exist at runtime, hence no storage may be set aside for it, hence implementation wise there is nothing to point at. In future I guess you could alter the language rules around this such that named constants could also have the target attribute, but the specification of such a change may be quite difficult to do without creating problems elsewhere.

A common thread to both aspects is that the association status of a pointer in isolation is not part of the value of the thing being pointed at, but the pointer association status of a pointer component of an object is part of the value of that object.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.