FORTRAN 77 Language Reference

Pointers

The POINTER statement establishes pairs of variables and pointers. @ Each pointer contains the address of its paired variable.

Syntax Rules


	POINTER ( p1, v1 ) [, ( p2, v2 ) ... ] 

The POINTER statement has the following syntax:

where:

A pointer-based variable is a variable paired with a pointer in a POINTER statement. A pointer-based variable is usually just called a based variable. The pointer is the integer variable that contains the address.

Example: A simple POINTER statement:


	POINTER ( P, V )

Here, V is a pointer-based variable, and P is its associated pointer.

See "POINTER", for more examples.

Usage of Pointers

Normal use of pointer-based variables involves the following steps. The first two steps can be in either order.

  1. Define the pairing of the pointer-based variable and the pointer in a POINTER statement.

  2. Define the type of the pointer-based variable.

    The pointer itself is integer type and should not appear in a type declaration.

  3. Set the pointer to the address of an area of memory that has the appropriate size and type.

    You do not normally do anything else explicitly with the pointer.

  4. Reference the pointer-based variable.

    Just use the pointer-based variable in normal FORTRAN statements--the address of that variable is always from its associated pointer.

Address and Memory

No storage for the variable is allocated when a pointer-based variable is defined, so you must provide an address of a variable of the appropriate type and size, and assign the address to a pointer, usually with the normal assignment statement or data statement.

The loc(), malloc(), and free() routines associate and deassociate memory addresses with pointers. (These routines are described in Chapter 6.)

When compiled for 64-bit environments, pointers declared by the POINTER statement are INTEGER*8 values.

Address by LOC() Function

You can obtain the address from the intrinsic function LOC().

Example: Use the LOC() function to get an address:


* ptr1.f: Assign an address via LOC() 
	POINTER ( P, V ) 
	CHARACTER A*12, V*12 
	DATA A / 'ABCDEFGHIJKL' / 
	P = LOC( A ) 
	PRINT *, V(5:5) 
	END

In the above example, the CHARACTER statement allocates 12 bytes of storage for A, but no storage for V. It merely specifies the type of V because V is a pointer-based variable, then assign the address of A to P, so now any use of V will refer to A by the pointer P. The program prints an E.

When compiled for 64-bit environments, LOC() returns an INTEGER*8 value. The receiving variable must be either a pointer or an INTEGER*8 variable to avoid possible address truncation.

Memory and Address by MALLOC() Function

The function MALLOC() allocates an area of memory and returns the address of the start of that area. The argument to the function is an integer specifying the amount of memory to be allocated, in bytes. If successful, it returns a pointer to the first item of the region; otherwise, it returns an integer 0. The region of memory is not initialized in any way.

Example: Memory allocation for pointers, by MALLOC


	COMPLEX Z
	REAL X, Y
	POINTER ( P1, X ), ( P2, Y ), ( P3, Z ) 
	... 
	P1 = MALLOC ( 10000 ) 
	... 

:

In the above example, MALLOC() allocates 10,000 bytes of memory and associates the address of that block of memory with the pointer P1.

Deallocation of Memory by FREE() Subroutine

The subroutine FREE() deallocates a region of memory previously allocated by MALLOC(). The argument given to FREE() must be a pointer previously returned by MALLOC(), but not already given to FREE(). The memory is returned to the memory manager, making it unavailable to the programmer.

Example: Deallocate via FREE:


	POINTER ( P1, X ), ( P2, Y ), ( P3, Z ) 
	... 
	P1 = MALLOC ( 10000 ) 
	... 
	CALL FREE ( P1 ) 
	... 

In the above example, MALLOC() allocates 10,000 bytes of memory, which are associated with pointer P1. FREE() later returns those same 10,000 bytes to the memory manager.

Special Considerations

Here are some special considerations when working with pointers and memory allocation with malloc(), loc(), and free():

Optimization and Pointers

Pointers have the annoying side effect of reducing the assumptions that the global optimizer can make. For one thing, compare the following:

Therefore, the optimizer must assume that a variable passed as an argument in a subroutine or function call can be changed by any other call. Such an unrestricted use of pointers would degrade optimization for the vast majority of programs that do not use pointers.

General Guidelines

There are two alternatives for optimization with pointers.

The second choice also has a suboption: localize pointers to one routine and do not optimize it, but do optimize the routines that do the calculations. If you put the calling the routines on different files, you can optimize one and not optimize the other.

Example: A relatively "safe" kind of coding with -O3 or -O4:


	REAL A, B, V(100,100) 	 This programming unit does
	POINTER ( P, V )      	   nothing else with P other than  
	P = MALLOC(10000)     	 getting the address and passing it.
	... 
	CALL CALC ( P, A )
	...
	END

	SUBROUTINE CALC ( ARRAY, X )
	...
	RETURN
	END

If you want to optimize only CALC at level -O4, then avoid using pointers in CALC.

Some Problematic Code Practices

Any of the following coding practices, and many others, could cause problems with an optimization level of -O3 or -O4:

Example: Code that could cause trouble with -O3 or -O4:


	COMMON A, B, C 
	POINTER ( P, V ) 
	P = LOC(A) + 4 			  Possible problems here if optimized
	... 

The compiler assumes that a reference through P may change A, but not B; this assumption could produce incorrect code.