Is it legal to use an non-associated pointer to call a type-bound procedure?

  • Follow


Hello,

I think I know the answer to my title question (that being "yes"), but
I just want to make sure.
Here is a small program that illustrates the issue:

module type_bound

    implicit none

    type :: mytype
        character(len=20) :: name
    contains
        procedure :: describe => describe_mytype
    end type mytype

contains
subroutine describe_mytype( this, available )
    class(mytype) :: this
    logical       :: available

    !
    ! How do we make the argument "this" a pointer? How do we know it?
    !
    if ( available ) then
        write(*,*) this%name
    else
        write(*,*) '-- not associated --'
    endif
end subroutine describe_mytype

end module type_bound

program test_type_bound

    use type_bound
    type(mytype), pointer :: anobject => null()

    call anobject%describe( associated(anobject) )

end program test_type_bound

(I indicate the association status explicitly, because I do not know
how to use "anobject"
as a pointer directly in the describe_mytype procedure - that is: pass
the "pointer" attribute)

In the above program "anobject" is a pointer variable that is not
associated with any actual
object of type "mytype". But as the describe procedure is a type-bound
procedure, I merely
use "anobject"'s type and not the memory it does or does not refer to.
So I think this is
perfectly legal. Am I right? (I tried it with two compilers and they
both gave the answer
I expected, but that is merely circumstantial evidence of course)

Regards,

Arjen
0
Reply arjen.markus895 (634) 1/6/2011 10:57:57 AM

On 06/01/11 21:57, Arjen Markus wrote:
....
> (I indicate the association status explicitly, because I do not know
> how to use "anobject"
> as a pointer directly in the describe_mytype procedure - that is: pass
> the "pointer" attribute)
>
> In the above program "anobject" is a pointer variable that is not
> associated with any actual
> object of type "mytype". But as the describe procedure is a type-bound
> procedure, I merely
> use "anobject"'s type and not the memory it does or does not refer to.
> So I think this is
> perfectly legal. Am I right? (I tried it with two compilers and they
> both gave the answer
> I expected, but that is merely circumstantial evidence of course)

12.5.1 in F2008.  The /data-ref/ in a /procedure-designator/ shall not 
be an unallocated allocatable variable _or a pointer that is not 
associated_.  Penalty thirty lashes.

What are you actually trying to do?  Perhaps "describe" could just be a 
normal procedure that takes a pointer argument, tests it's association 
status and then calls a type bound procedure binding "do_describe" if 
the status is associated?
0
Reply ian_harvey (217) 1/6/2011 12:48:15 PM


Hello,

On 01/06/2011 11:57 AM, Arjen Markus wrote:
> I think I know the answer to my title question

Pre-remark: "non-associated" is not a well-defined state as a pointer 
has three different states and not just two: "associated, disassociated, 
or undefined.". I assume, you mean "disassociated" ("nullified").

To your question: My answer would be "no". From the formal point of 
view, your CALL to a type-bound procedure (TBP) is:

R1220 call-stmt is CALL procedure-designator [([actual-arg-spec-list])]
R1221 procedure-designator is procedure-name
                            or proc-component-ref
                            or data-ref % binding-name

where the TBP is the last item ("data-ref % binding-name"). For the data 
ref, I would claim that the following holds:

"A reference is permitted only if the variable is defined. A reference 
to a data pointer is permitted only if the pointer is associated with a 
target object that is defined." (F2008, "6.2 Variable")


>      type(mytype), pointer :: anobject =>  null()
>      call anobject%describe( associated(anobject) )

Replace TYPE by CLASS and tell me then what the compiler should do. But 
also for TYPE: Depending on the implementation, the called procedure 
(which has a polymorphic dummy argument!) might need to to access 
(hidden) data, which might not be present if the pointer is not associated.

Thus, while the chance is high that it works for TYPE, it will likely 
fail with CLASS and with some compilers also TYPE might not work.

I think one could allow it (both for TYPE and CLASS - via the declared 
type) but it would mean to change lots of places in the standard for 
little gain.

Instead of using:

     call anobject%describe( associated(anobject) )

you could do:

     call describe_mytype (type)
or
     if (associated(anobject)) &
       call anobject%describe ()

> (I indicate the association status explicitly, because I do not know
> how to use "anobject"
> as a pointer directly in the describe_mytype procedure - that is: pass
> the "pointer" attribute)

That's not possible:

"C456   The passed-object dummy argument shall be a scalar, nonpointer, 
nonallocatable dummy data object with the same declared type as the type 
being dened; all of its length type parameters shall be assumed;
it shall be polymorphic (4.3.1.3) if and only if the type being defined 
is extensible (4.5.7). It shall not have the VALUE attribute."


> I merely use "anobject"'s type and not the memory it does or does not refer to.

Well, as mentioned before: The compiler might use memory which it refers 
to - e.g. for the type. As the type is known at compile time, most 
compilers will directly call the procedure. If the type is not known 
(polymorphic type, CLASS), most compilers use a lookup table (vtable) 
with procedure pointers to the actual procedure. Thus, if you then have 
a not-associated pointer, the chance of getting a segfault is very high.

Tobias
0
Reply burnus (564) 1/6/2011 1:03:22 PM

On 6 jan, 13:48, Ian Harvey <ian_har...@bigpond.com> wrote:
> On 06/01/11 21:57, Arjen Markus wrote:
> ...
>
> > (I indicate the association status explicitly, because I do not know
> > how to use "anobject"
> > as a pointer directly in the describe_mytype procedure - that is: pass
> > the "pointer" attribute)
>
> > In the above program "anobject" is a pointer variable that is not
> > associated with any actual
> > object of type "mytype". But as the describe procedure is a type-bound
> > procedure, I merely
> > use "anobject"'s type and not the memory it does or does not refer to.
> > So I think this is
> > perfectly legal. Am I right? (I tried it with two compilers and they
> > both gave the answer
> > I expected, but that is merely circumstantial evidence of course)
>
> 12.5.1 in F2008. =A0The /data-ref/ in a /procedure-designator/ shall not
> be an unallocated allocatable variable _or a pointer that is not
> associated_. =A0Penalty thirty lashes.
>
> What are you actually trying to do? =A0Perhaps "describe" could just be a
> normal procedure that takes a pointer argument, tests it's association
> status and then calls a type bound procedure binding "do_describe" if
> the status is associated?

I constructed this example while trying to simplify another one where
the objects may or may not have certain components. What I currently
do
(just some toy programs, mind you), is first check that the component
is there and then call the procedure. I thought that calling the type-
bound
procedure directly (without checking the association status) would
simplify
matters.

But as Tobias points out: this may work - coincidentally - for types,
it won't do so for classes. The point is clear and I can mark off one
more question :).

Regards,

Arjen
0
Reply arjen.markus895 (634) 1/6/2011 1:12:31 PM

On 6 jan, 14:03, Tobias Burnus <bur...@net-b.de> wrote:
> Hello,
>
> On 01/06/2011 11:57 AM, Arjen Markus wrote:
>
> > I think I know the answer to my title question
>
> Pre-remark: "non-associated" is not a well-defined state as a pointer
> has three different states and not just two: "associated, disassociated,
> or undefined.". I assume, you mean "disassociated" ("nullified").
>
> To your question: My answer would be "no". From the formal point of
> view, your CALL to a type-bound procedure (TBP) is:
>
> R1220 call-stmt is CALL procedure-designator [([actual-arg-spec-list])]
> R1221 procedure-designator is procedure-name
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 or proc-component=
-ref
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 or data-ref % bin=
ding-name
>
> where the TBP is the last item ("data-ref % binding-name"). For the data
> ref, I would claim that the following holds:
>
> "A reference is permitted only if the variable is defined. A reference
> to a data pointer is permitted only if the pointer is associated with a
> target object that is defined." (F2008, "6.2 Variable")
>
> > =A0 =A0 =A0type(mytype), pointer :: anobject =3D> =A0null()
> > =A0 =A0 =A0call anobject%describe( associated(anobject) )
>
> Replace TYPE by CLASS and tell me then what the compiler should do. But
> also for TYPE: Depending on the implementation, the called procedure
> (which has a polymorphic dummy argument!) might need to to access
> (hidden) data, which might not be present if the pointer is not associate=
d.
>
> Thus, while the chance is high that it works for TYPE, it will likely
> fail with CLASS and with some compilers also TYPE might not work.
>
> I think one could allow it (both for TYPE and CLASS - via the declared
> type) but it would mean to change lots of places in the standard for
> little gain.
>
> Instead of using:
>
> =A0 =A0 =A0call anobject%describe( associated(anobject) )
>
> you could do:
>
> =A0 =A0 =A0call describe_mytype (type)
> or
> =A0 =A0 =A0if (associated(anobject)) &
> =A0 =A0 =A0 =A0call anobject%describe ()
>
> > (I indicate the association status explicitly, because I do not know
> > how to use "anobject"
> > as a pointer directly in the describe_mytype procedure - that is: pass
> > the "pointer" attribute)
>
> That's not possible:
>
> "C456 =A0 The passed-object dummy argument shall be a scalar, nonpointer,
> nonallocatable dummy data object with the same declared type as the type
> being de ned; all of its length type parameters shall be assumed;
> it shall be polymorphic (4.3.1.3) if and only if the type being defined
> is extensible (4.5.7). It shall not have the VALUE attribute."
>
> > I merely use "anobject"'s type and not the memory it does or does not r=
efer to.
>
> Well, as mentioned before: The compiler might use memory which it refers
> to - e.g. for the type. As the type is known at compile time, most
> compilers will directly call the procedure. If the type is not known
> (polymorphic type, CLASS), most compilers use a lookup table (vtable)
> with procedure pointers to the actual procedure. Thus, if you then have
> a not-associated pointer, the chance of getting a segfault is very high.
>
> Tobias

Yes, I did mean disassociated - I did not think of the right term.
Your
explanation does make sense. It is nothing crucial (see my answer to
Ian),
just a matter of getting a clearer understanding.

Regards,

Arjen
0
Reply arjen.markus895 (634) 1/6/2011 1:15:22 PM

Tobias Burnus <burnus@net-b.de> wrote:

> Hello,
> 
> On 01/06/2011 11:57 AM, Arjen Markus wrote:
> > I think I know the answer to my title question
> 
> Pre-remark: "non-associated" is not a well-defined state as a pointer
> has three different states and not just two: "associated, disassociated,
> or undefined.". I assume, you mean "disassociated" ("nullified").

Interesting. As you suggest, the standard doesn't define a term
"non-associated", but my ear for English suggests that, lacking a
specific technical definition to the contrary, it would mean "not
associated", which is to say either disassociated or undefined.

I'd say that your answer (that it is not legal) applies to that as well.
In fact, Ian's quote from 12.5.1 uses "not associated", which I find
indistinguishable from non-associated.

I realize from his reply that Arjen says he meant disassociated, but I
think the question makes sense either way (and has the same answer). In
fact, I think the answer is, if anything, more evident for the undefined
case than the disassociated case. Not bothering to crack the standard
right now to check, as I'm not yet awake enough to read it very well
anyway, but I'd think that a disassociated class pointer ought to at
least have a well-defined dynamic type (which seems like it ought to be
the same as the declared type). A class pointer with undefined
association status pretty much has to also have undefined dynamic type,
which could imply ambiguity in what type-bound procedure was selected.

-- 
Richard Maine                    | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle           |  -- Mark Twain
0
Reply nospam47 (9742) 1/6/2011 5:02:53 PM

5 Replies
45 Views

(page loaded in 0.115 seconds)

Similiar Articles:









7/23/2012 4:58:32 AM


Reply: