Cryptic error message for procedure bound to a type

Tobias Burnus burnus@net-b.de
Wed Sep 8 17:16:00 GMT 2010


  On 09/08/2010 05:56 PM, Armelius Cameron wrote:
> On Wednesday, September 08, 2010 10:50:35 am Tobias Burnus wrote:
>> 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 de
ned is
>> extensible (4.5.7). It shall not have the VALUE attribute.
> More question, the last phrase of the standard: "...if and only if the type
> being defined is extensible (4.5.7) ", what type is not extensible then ?

Well, if one goes to 4.5.7 (for links to the standards see 
http://gcc.gnu.org/wiki/GFortranStandards ; my quotes are from Fortran 
2008), one finds:

"A derived type that does not have the BIND attribute or the SEQUENCE 
attribute is an extensible type."

> (It's an honest question, not trying to be sarcastic :) ). Does all PASS-ed argument
> of type-bound procedure need be "CLASS(..)" then ?

I think so. At least I read the constraint C456 together with the 
definition from 4.5.7 as such. While there are non-extensible types, 
namely those with BIND(C) and SEQUENCE, type bound procedures are only 
allowed for extensible types:

C436 (R425) If SEQUENCE appears, each data component shall be declared 
to be of an intrinsic type or of a sequence type, and a 
type-bound-procedure-part shall not appear.

C1504 (R425) A derived type with the BIND attribute shall not have a 
type-bound-procedure-part.

Thus, the only possibility I see is a SEQUENCE type with a 
procedure-pointer components:

type t
   sequence
   procedure(sub), pointer :: ptr
end type t
interface
   subroutine sub(x)
     import
     type(t) :: x
   end subroutine
end interface


> What is the different in the implementation of the procedure if I use "CLASS()"
> instead of TYPE() ?

Well, if you only access the components of the declared type: 
effectively nothing. However, if you use a type-bound procedure, e.g.
   subroutine foo(a)
     class(t) :: a
     a%tbp()
the procedure cannot be called directly but one accesses via the data 
provided in "a" a lookup table for the effective type (vtable) which 
contains then the address of the function to be called.

Thus, with CLASS type-bound procedures and type-bound operators are a 
bit slower as there are additional look ups involved and the function 
being called cannot be inlined. Operating directly on the data - or 
calling functions within
   SELECT TYPE (type)
       TYPE IS ...
are again compile time resolvable and should thus be again be inlinable 
- though some us are lost due to the SELECT TYPE.

Cf. http://gcc.gnu.org/wiki/OOP for the vtable layout gfortran uses.

> BTW, the book "Fortran 2003 Handbook" by Adams, Brainerd, et all gives an
> example similar to my code on page 89 (using TYPE() instead of CLASS() for the
> dummy argument); and the code from the book is also rejected (with the same
> message) by gfortran. I guess the book example is wrong then ?

I guess so. I think the standard is pretty clear in this case. (In 
general, one can easily misread the standard by either misinterpreting 
some statement - or by not finding the relevant statement. That even 
happens quite experienced members of the standardization committee. For 
me misreading happens more regularly.)

Tobias



More information about the Fortran mailing list