Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compare two pointers

I recently came across the question of how to compare two pointers in Fortran. In C one can compare two pointers with (pA == pB) (with pA and pB being pointers) as they are just addresses. But in fortran pointers are more than pure memory addresses. The code if(pa.ne.pb) (with pa and pb being pointers of the same type) gives me an error

Operands of comparison operator '.ne.' at (1) are TYPE(sometype)/TYPE(sometype)

where sometype is the type the pointer is pointing to.

Is there a way to compare whether two pointers point to the same target? Or do I have to create a .ne.-operator for the type being pointed to?

like image 692
PVitt Avatar asked Oct 23 '15 12:10

PVitt


People also ask

Can you compare two pointers?

We can compare pointers if they are pointing to the same array. Relational pointers can be used to compare two pointers. Pointers can't be multiplied or divided.

Is it possible to compare two pointers Why?

In Go language, you are allowed to compare two pointers with each other. Two pointers values are only equal when they point to the same value in the memory or if they are nil. You can perform a comparison on pointers with the help of == and !=

How do you find the difference between two pointers?

The subtraction of two pointers gives the increments between the two pointers. For Example: Two integer pointers say ptr1(address:1000) and ptr2(address:1016) are subtracted. The difference between address is 16 bytes.

Can you compare pointers with ==?

Comparison operators can be used to compare two pointers. Only equality operators (operator== and operator!=) can be used to compare the following pointer pairs: two pointers-to-members. a null pointer constant with a pointer or a pointer-to-member.


2 Answers

As High Performance Mark comments the associated intrinsic can partly do what you want:

if (.not.ASSOCIATED(pa, pb)) ...

In many cases, using associated with two pointer arguments will tell you whether the two targets "occupy the same storage units". In some senses this is the case when the pointers are pointing to the same target.

integer, target :: a
integer, pointer :: pa, pb
pa=>a; pb=>a

print*, ASSOCIATED(pa, pb)

Alas, things aren't so simple.

Another restriction for scalar targets is that they are not zero-sized storage. Take the following case

type t
end type t

type(t), target :: a
type(t), pointer :: pa, pb
pa=>a; pb=>a

print*, ASSOCIATED(pa, pb)

The output of this, if a variable of type t has zero-sized storage, must be .FALSE., even though they are certainly the same target. The storage size of an object of type t is an implementation detail.

The same holds for zero-sized arrays, although it is clear that the result here is .FALSE.:

integer, target :: a(0)
integer, pointer :: pa(:), pb(:)
pa=>a; pb=>a

print*, ASSOCIATED(pa, pb)

If you have such pathological cases of the first kind that you care about there may be a possibility to consider using C addresses and Fortran 2003 C interoperability.

The c_associated function compares the C addresses determined by c_loc. Continuing the above code with type(t) targets,

print*, C_ASSOCIATED(C_LOC(pa), C_LOC(pb))

may be more forgiving. Again, whether it works depends on the implementation.

This approach with C addresses will not help in the case of zero-length strings or zero-sized arrays: using c_loc is prohibited in these cases.

To conclude, it is generally the case that ASSOCIATED(pa, pb) returns .TRUE. if and only if pa and pb point to the same target, but there are exceptions in both directions.

like image 59
francescalus Avatar answered Sep 20 '22 12:09

francescalus


The associated() function takes a second optional pointer argument. You can then test if both pointers are associated with the same target:

if (associated(pA, pB)
like image 29
Vladimir F Героям слава Avatar answered Sep 18 '22 12:09

Vladimir F Героям слава