(j3.2006) Unlimited polymorphic and LOCK_TYPE (and EVENT_TYPE)

Malcolm Cohen malcolm
Wed Jun 4 02:31:17 EDT 2014


>C438 prevents hiding a component of type LOCK_TYPE under an extension of
>a declared type that doesn't have a component of type LOCK_TYPE, using a
>polymorphic object of that declared type, to circumvent C1304.
>
>If it is important to have a constraint against that, it seems important
>to constrain against hiding an object involving type LOCK_TYPE under an
>an unlimited polymorphic object.

I do not really agree.

For example, we are type-strict with pointer assignment and any declared type, 
but not with unlimited polymorphic: here we permit unsafe pointer assignment 
with SEQUENCE and BIND(C) types, because that cannot be checked at compile-time 
and those types are excluded from SELECT TYPE because it was thought 
unreasonable to require the processor to do runtime type conformance checking of 
SEQUENCE and BIND(C) types via CLASS(*).

That is, when we agree that the requirement for functionality outweighs the 
requirement for safety, we permit the functionality.

Permitting CLASS(*) to be used in ways that potentially violate requirements 
(but not compile-time-checkably), does not mean the rest of our type-safety 
constraints are useless.  On the contrary, they ensure that in the normal course 
of events the programmer has the safety, and only if he needs the functionality 
that is provided by CLASS(*) does he lose that guarantee.  That is definitely a 
minority of cases.

For the issue in question, that is "do we want to allow CLASS(*) to reference 
LOCK_TYPE", we *could* decide that the functionality is not important enough (or 
simply not usable as is anyway), and so remove that ability from CLASS(*).  I 
might still have a philosophical objection to that (what's the point of having a 
"root type" if there are types it cannot encompass?) but I might be convinced on 
the pragmatic grounds.

>A simpler example than the earlier one would be
>
>  type(lock_type), save, target :: A[*], B[*]
>  class(*), allocatable :: C, D
>  logical :: GOT_IT
>
>  lock ( a )
>  allocate ( c, source=a ) ! locks c

Well, creates a "locked" C if we have value semantics.
With reference semantics, C is the same lock as A.
With positional semantics, plausible results are
(a) a different lock, unlocked
(b) a different lock, locked
(c) not a lock at all.
WIth unspecified different semantics, anything we like.

>  select type ( c )
>  type is ( lock_type )
>    lock ( c, acquired_lock = got_it )

With positional semantics, plausible results are
(a) acquired_lock = TRUE
(b) acquired_lock = FALSE
(c) error termination (could have been caught with STAT=)
(d) seg fault (not catchable with STAT=)
etc.

>    if ( .not. got_it ) print *, "How was C already locked?"
>  end select
>
>  allocate ( d, source=b ) ! unlocks d

Well, creates an "unlocked" D if we have value semantics etc.

>  c = d ! unlocks c

Maybe.

>  select type ( c )
>  type is ( lock_type )
>    lock ( c, acquired_lock = got_it )
>    if ( got_it ) print *, "How did C get locked again?"
>  end select

I think all these examples are nonconforming because, as Nick keeps reminding 
us, we do not specify whether locks have reference or value semantics (or 
position semantics for that matter).  As long as we stick to normal usage and 
the normal rules, that's usually not a problem (normal usage should give the 
same result regardless).  But the results from these examples for value, 
reference, or position semantics are all different.  There are also variations 
on RefValPos that give even more possible variety!  Therefore by clause 1, no 
interpretation is established.

>Do we want to constrain against this, or not?

Good question.  Next question?

...
>(It would be helpful if items(1-7) of 7.2.1.2 were in constraints.)

How many compilers fail to diagnose these errors?

Apart, that is, from compiler extensions (e.g. we allow assignment to ISO 10646 
from anything).

>Constraining against pointer assigning an object involving type
>LOCK_TYPE to an unlimited polymorphic object is still necessary,

I think there might also be issues with LOCK_TYPE actual arguments and ordinary 
CLASS(*) dummy arguments.

Despite my philosophical objections, I lean slightly towards doing *something* 
about all this.  That is, if we can agree on What Needs To Be Done.

Cheers,
-- 
................................Malcolm Cohen, Nihon NAG, Tokyo. 




More information about the J3 mailing list