!standard 13.13.2 02-06-11 AC95-00039/01 !class binding interpretation 02-06-11 !status received no action 02-06-11 !subject Incomplete types and dispatching. !summary !appendix From: Pascal Leroy Sent: Tuesday, April 23, 2002 4:03 AM The fact that incomplete types do not indicate whether their completion is tagged or not seems to cause a number of problems when the completion (of an incomplete type declared in a private part) occurs in the body. Consider the following package: package P is private type T1; type T2; procedure Q (X1 : access T1; X2 : access T2); end; One would hope that if T1 and T2 turn out to be tagged, an error would be detected somewhere, but there seems to be no rule to that effect. But consider now the case where the completion of T1 is tagged and the completion of T2 isn't. This would seem to be legal, except that it means that we now have to generate code for calls to Q (for instance in a child of P) without knowing if Q is a dispatching operation of some tagged type. This is rather inconvenient. It would be nice if we always knew, at the point of the declaration of a subprogram, whether it is a primitive operation of a tagged type or not. Evidently, incomplete tagged types would help tremendously. **************************************************************** From: Tucker Taft Sent: Tuesday, April 23, 2002 9:07 AM > Evidently, incomplete tagged types would help tremendously. I agree that we should make 'Class on an incomplete type *without* "is tagged" obsolescent. I would be reluctant to just outlaw it, but perhaps we could be bold and do so. **************************************************************** From: Pascal Leroy Sent: Tuesday, April 23, 2002 10:10 AM But wait, this has nothing to do with 'Class, there may be no use of 'Class on the incomplete type, but still we have a dispatching operation and we don't know it. I wonder how compilers handle that today. I'm pretty sure that our compiler is not really prepared to deal with the examples that I gave in my original message. **************************************************************** From: Gary Dismukes Sent: Tuesday, April 23, 2002 1:40 PM Pascal wrote: > > package P is > private > type T1; > type T2; > procedure Q (X1 : access T1; X2 : access T2); > end; > > One would hope that if T1 and T2 turn out to be tagged, an error would be > detected somewhere, but there seems to be no rule to that effect. It would seem that 3.9.2(12) applies as normal. Of course this can't be checked until the body is compiled, but it still has to be checked. Why do you think that rule doesn't apply in this case? > But consider now the case where the completion of T1 is tagged and the > completion of T2 isn't. This would seem to be legal, except that it means > that we now have to generate code for calls to Q (for instance in a child of > P) without knowing if Q is a dispatching operation of some tagged type. > This is rather inconvenient. I guess this partly depends on whether the implementation has some dependence on knowing whether a call is a dispatching operation in order to make an ordinary (nondispatching) call. I would think that most implementations don't have such a dependence, but it sounds like you're saying that yours does, is that correct? Now if it's also possible to make a dispatching call to such an operation, then I agree there could be a general problem here. The case of concern seems to be when there are access-to-class-wide types declared in the private part of the package and there's a call to the operation, passing values of the class-wide access types, from a point where the type views are still incomplete. I agree that's a problem, unless we can make such calls illegal. > It would be nice if we always knew, at the point of the declaration of a > subprogram, whether it is a primitive operation of a tagged type or not. True, though it would an incompatible change to require this of course (that is, to disallow 'Class unless the incomplete type is know to be tagged). But maybe that would be an acceptable incompatibility. In the context of the current rules, for the dispatching case it seems that a dispatching call should be made illegal if the type views are incomplete. Since such a call effectively involves a dereference of the access actuals, it would be nice to have the rule against dereferences of incomplete types apply, though it doesn't seem to directly apply here (but maybe there's a way of interpreting this that I'm missing). One way to do it would simply be to disallow a dynamically tagged actual for an access formal whose designated type is not known to be tagged. > Evidently, incomplete tagged types would help tremendously. Indeed, too bad that wasn't thought of during the design... In a later message you replied to Tucker: > > > I agree that we should make 'Class on an incomplete type *without* > > "is tagged" obsolescent. I would be reluctant to just outlaw it, > > but perhaps we could be bold and do so. > > But wait, this has nothing to do with 'Class, there may be no use of 'Class > on the incomplete type, but still we have a dispatching operation and we > don't know it. > > I wonder how compilers handle that today. I'm pretty sure that our compiler > is not really prepared to deal with the examples that I gave in my original > message. Again it sounds like you're concerned with the nondispatching case. Are you saying that you have a special calling sequence required when making a nondispatching call to a dispatching operation? Normally it seems that such a call would be treated as an ordinary subprogram call, but if that's not true for Rational then this does indeed seem like a tricky implementation problem that might require the suggested incompatible language change. **************************************************************** From: Pascal Leroy Sent: Tuesday, April 23, 2002 3:29 PM > I guess this partly depends on whether the implementation has some > dependence on knowing whether a call is a dispatching operation > in order to make an ordinary (nondispatching) call. I would think > that most implementations don't have such a dependence, but it > sounds like you're saying that yours does, is that correct? No, I don't think we have such a dependency. I was thinking of dispatching calls, sorry if I was unclear. > Now if it's also possible to make a dispatching call to such an > operation, then I agree there could be a general problem here. > The case of concern seems to be when there are access-to-class-wide > types declared in the private part of the package and there's a > call to the operation, passing values of the class-wide access > types, from a point where the type views are still incomplete. > I agree that's a problem, unless we can make such calls illegal. That's exactly what I had in mind. > > It would be nice if we always knew, at the point of the declaration of a > > subprogram, whether it is a primitive operation of a tagged type or not. > > True, though it would an incompatible change to require this of course > (that is, to disallow 'Class unless the incomplete type is know to > be tagged). But maybe that would be an acceptable incompatibility. This incompatibility seems acceptable to me, as it would be statically detected (usages of 'Class would become illegal) and the fix would be straightforward (add the word tagged). Moreover, we are talking a rather exotic feature here. > In the context of the current rules, for the dispatching case it seems > that a dispatching call should be made illegal if the type views are > incomplete. Since such a call effectively involves a dereference of > the access actuals, it would be nice to have the rule against dereferences > of incomplete types apply, though it doesn't seem to directly apply here > (but maybe there's a way of interpreting this that I'm missing). One way > to do it would simply be to disallow a dynamically tagged actual > for an access formal whose designated type is not known to be tagged. This could work, but it seems quite convoluted. **************************************************************** From: Randy Brukardt Sent: Tuesday, April 23, 2002 8:21 PM > > Now if it's also possible to make a dispatching call to such an > > operation, then I agree there could be a general problem here. > > The case of concern seems to be when there are access-to-class-wide > > types declared in the private part of the package and there's a > > call to the operation, passing values of the class-wide access > > types, from a point where the type views are still incomplete. > > I agree that's a problem, unless we can make such calls illegal. > > That's exactly what I had in mind. Could you write an example of the problem? While I would love to outlaw 'Class on incomplete types (preferably in 1994 :-), I don't see the problem. In order to get a dispatching call, you have to have a dynamically tagged type. The only way to get one for an incomplete type is to write a class-wide access type. But then you have the explicit 'Class, so it is clear (at least semantically) that the full type is tagged and the call must be dispatching. 'Knowing' that the type is tagged seems like it might be painful in some compilers, but it does seem to be known. My best guess of the example would be: package P is ... private type T1; type Acc_to_T1_Class is access T1'Class; procedure Q (X1 : access T1); end; package P.C is A : P.Acc_to_T1_Class := ...; ... end P.C; package body P.C is ... P.Q (A); -- Dispatches. end P.C; I don't see a real semantic problem here, although there may be implementation issues. **************************************************************** Editor's note: After many weeks, I privately received a message from the original questioner saying that he could not find an appropriate example. So it appears that there is no problem here. ****************************************************************