From: Ian Harvey on
(...bump, and see below...)

On 2/05/2010 9:04 AM, Ian Harvey wrote:
> Is there a way to suppress the intrinsic assignment of a derived type,
> so that an attempt to use intrinsic assignment (versus defined
> assignment) results in a compile time error?
>
> As background: I am in the habit of using the only clause in use
> statements to make it clearer where use associated things come from and
> avoid procedure name collisions. But when I then forget to include
> assignment(=) in the only clause I get some rather hard to diagnose
> bugs. The defined assignment was required to appropriately handle some
> pointer components of the type - the example below has a nonsense
> defined assignment just to illustrate the problem.
>
>
> ! Defines a type with defined assignment
> MODULE TypeDefinition
> IMPLICIT NONE
> PRIVATE
> PUBLIC :: ASSIGNMENT(=)
> PUBLIC :: Get
> PUBLIC :: Set
>
> TYPE, PUBLIC :: MyType
> PRIVATE
> INTEGER :: comp
> END TYPE MyType
>
> INTERFACE ASSIGNMENT(=)
> MODULE PROCEDURE assign_mytype
> END INTERFACE ASSIGNMENT(=)
>
> INTERFACE Set
> MODULE PROCEDURE set_mytype
> END INTERFACE Set
>
> INTERFACE Get
> MODULE PROCEDURE get_mytype
> END INTERFACE Get
> CONTAINS
> SUBROUTINE assign_mytype(lhs, rhs)
> TYPE(MyType), INTENT(OUT) :: lhs
> TYPE(MyType), INTENT(IN) :: rhs
> !****
> lhs%comp = rhs%comp + 1
> END SUBROUTINE assign_mytype
>
> SUBROUTINE set_mytype(obj, val)
> TYPE(MyType), INTENT(OUT) :: obj
> INTEGER, INTENT(IN) :: val
> !****
> obj%comp = val
> END SUBROUTINE set_mytype
>
> FUNCTION get_mytype(obj) RESULT(val)
> TYPE(MyType), INTENT(IN) :: obj
> INTEGER :: val
> !****
> val = obj%comp
> END FUNCTION get_mytype
> END MODULE TypeDefinition
>
> ! Example usage of our types.
> PROGRAM OnlyAssignment
> IMPLICIT NONE
> CALL type_only
> CALL type_and_assignment
> CONTAINS
> SUBROUTINE type_only
> USE TypeDefinition, ONLY: MyType, Set, Get
> TYPE(MyType) :: a
> TYPE(MyType) :: b
> !****
> CALL Set(a, 1)
> b = a
> WRITE (*, "(A20,I0)") 'TypeOnly:', Get(b)
> END SUBROUTINE type_only
>
> SUBROUTINE type_and_assignment
> USE TypeDefinition, ONLY: MyType, Set, Get, ASSIGNMENT(=)
> TYPE(MyType) :: a
> TYPE(MyType) :: b
> !****
> CALL Set(a, 1)
> b = a
> WRITE (*, "(A20,I0)") 'TypeAndAssignment:', Get(b)
> END SUBROUTINE type_and_assignment
> END PROGRAM OnlyAssignment

From the lack of response, I'll take the answer to the question as
being "No". A follow-up question:

One way of ensuring that the right assignment procedure gets called
appears (when supported by enough compilers) to be to make it a type
bound procedure.

TYPE MyType2
...
CONTAINS
GENERIC :: ASSIGNMENT(=) => assign_type2
END TYPE MyType2

My understanding though, is that this then means that each entity and
each call will come with all the baggage associated with type bound
procedures (akin to virtual calls and vtables in C++ implementations?).
Or does the specification of type bound procedures in the standard
mean that compilers can see that the type isn't extended in a particular
use and so it can implement the assignment just like it would for F95
defined assignment?

What do existing complete F2003 implementations do?

I appreciate this is implementation specific, but I'm just trying to
understand what the implications of this sort of programming style might be.

If type bound procedure style assignment comes with a cost, then I think
the inability to supress intrinsic assignment is a language gap.

Ta,

IanH
From: Richard Maine on
Ian Harvey <ian_harvey(a)bigpond.com> wrote:

> On 2/05/2010 9:04 AM, Ian Harvey wrote:
> > Is there a way to suppress the intrinsic assignment of a derived type,
> > so that an attempt to use intrinsic assignment (versus defined
> > assignment) results in a compile time error?

> From the lack of response, I'll take the answer to the question as
> being "No".

I don't recall seeing your original post. I'm not sure whether that
means I really didn't see it or just read it quickly without answering
and then forgot about it. In any case, I'll confirm that the answer is
"no", so that you don't have to interpret the silence.

> One way of ensuring that the right assignment procedure gets called
> appears (when supported by enough compilers) to be to make it a type
> bound procedure.

Yes. That avoids a lot of problems. In fact, I'd be darn tempted to say
that the non-type-bound forms deserve deprecation someday. Certainly not
any day soon, as we are just now getting to where you can plausibly
count on a decent fraction of compilers to support the type-bound form.
But in the long run, it just seems a better way. How often does one want
the capability to define the same assignment differently in different
scopes? Rarely. How often does one want to make sure that one's defined
assignment gets used everywhere? Almost all the time.

I recall that things like accidentally getting intrinsic assignment were
specifically cited during development of the standard as among the
problems that type-bound assignment was going to help with.

> My understanding though, is that this then means that each entity and
> each call will come with all the baggage associated with type bound
> procedures (akin to virtual calls and vtables in C++ implementations?).
> Or does the specification of type bound procedures in the standard
> mean that compilers can see that the type isn't extended in a particular
> use and so it can implement the assignment just like it would for F95
> defined assignment?

I can't give you all the implementation details from my personal
knowledge. Have to ask the vendors that one. But I was told by people
who at least talked convincingly like they understood the issues
(convincingly enough for me) that the f2003 spec was avoiding a lot of
the overhead of C++ in this area. I think that avoidance of multiple
inheritance might have been one of the things that helped, but I could
well be confusing separate issues here. Maybe someone else can provide
more details.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
From: Arjen Markus on
A related question (it is much less useful than user-defined
assignment, but still):
is it possible to overload the pointer assignment operation?

I can imagine that could be handy to verify that you are pointing to
allocated memory
for instance or for garbage collection of sorts.

Regards,

Arjen
From: Reinhold Bader on
Hello,

Am 21.05.2010 17:02, schrieb Arjen Markus:
> A related question (it is much less useful than user-defined
> assignment, but still):
> is it possible to overload the pointer assignment operation?

No, this is presently not supported in any standard.

>
> I can imagine that could be handy to verify that you are pointing to
> allocated memory
> for instance or for garbage collection of sorts.

I agree this feature would be useful for the above purposes.

Regards
Reinhold

>
> Regards,
>
> Arjen

From: Richard Maine on
Arjen Markus <arjen.markus895(a)gmail.com> wrote:

> is it possible to overload the pointer assignment operation?

No, it is not.

> I can imagine that could be handy to verify that you are pointing to
> allocated memory
> for instance or for garbage collection of sorts.

Understand.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain