J3/00-114r1 Date: 11th February 2000 To: J3 From: Malcolm Cohen Subject: Issue 141 and a related problem 1. Introduction The editor is still unhappy about pointer assignment and type parameters. Now, we may have gotten things wrong here, but the specific complaints raised in 141 seem to be completely spurious. (Still, at least it had the effect of making me re-read the section and noticing that something appeared to be wrong). Section 2 will deal with issue 141. Section 3 will attempt to deal with nearby problems that may exist (but which are not issues). 2. Issue 141 details Issue 141 says: >What about type parameters in other cases where deferred type parameters >are not currently defined? These cases are addressed by the text inserted by 99-185r4. >Paper 99-185r4 partly addressed this question, but it appears incomplete. >It mentions only the case where target is a disassociated pointer. Actually, it mentions "NOT A DISASSOCIATED POINTER" (emphasis mine). >Three paras earlier, we felt it necessary to separately mention the cases >where target is a pointer with undefined association status An undefined pointer is "not a disassociated pointer", so we seem to have addressed this case (whether we got it right or not is another matter). >and where it was a reference to the NULL function. Why >did we have to distinguish those there and not here? Well, maybe we did not need to distinguish those earlier. I don't think this is sufficiently confusing to rate an issue. >Perhaps the NULL function case is ok - I'm not quite sure why we >distinguished that before (doesn't seem to me particularly different from >some other function that returns a dissasociated pointer). I think it is just an attempt to be careful in talking about the syntax "" and not the actual "target". But another paper has attempted to clarify the situation (see issue 222). In any case, issue 222 (which boils down to "we have too many targets") is an adequate pointer to the target confusion; therefore we can just delete this part of the issue. >But a pointer with undefined association >status is certainly different from a disasociated pointer. INDEED!!!!!!!!!!! Therefore, undefined pointers are covered. >Also the former version of issue 141 mentioned the case where a null >(should have said disassociated, I guess) pointer is an actual argument for >a pointer dummy. I see no edits or comments about that case. Can I assume >this means that it was looked at and determined not to be a problem? It seems to me that it is adequately addressed by issue 79, which also occurs within the chapter which contains the purported problem. >Or was this issue closed without actually checking that all the questions >it raised were addressed? No, we considered that this was simply a duplicate of issue 79. >Also, I find myself greatly confused by the revision that paper 99-185r1 >made to the above para. In addressing the issue of undefined type >parameter values, it appears to have changed the conditions on cases where >the type parameters are well defined. And I don't understand the change. You need to read it more carefully. >The former version of this para said that *ALL* nondeferred type parameters >of pointer-object had to agree with the corresponding type parameters of >target. The new version appears to allow disagreement as long as the type >parameter of target is deferred. This doesn't make sense to me. And it wouldn't make sense to me either; but it is not what the text says. The text has "not a disassociated pointer" and "otherwise". The lack of agreement requirement is governed by the "otherwise", i.e. applies only to disassociated pointers. However, I take the implied point that the paragraph is confusingly written; an edit below swaps the sentences so that the condition is stated in the positive rather than the negative. >(And this >isn't a constraint, so its not just a matter of checkability). There were >words explicitly added to single out that case, so its presumably not just >a matter of forgetting about the case. Right - for disassociated pointers, deferred type parameters have no defined value (one is not allowed even to ask about them). So it would be meaningless to attempt to require a defined value (defined by virtue of not being deferred) to be equal to a value that does not exist and that you are not allowed to ask about (because it is a deferred type parameter of a disassociated pointer). Perhaps two examples to clarify the situation: CHARACTER*10,POINTER :: p1 CHARACTER*(:),POINTER :: p2 => NULL() p1 => p2 In this example, p1=>p2 is legal. There is no requirement on the non-defined type parameter of p2 (the type parameter has no value). SUBROUTINE s(p1,p3) CHARACTER*10,POINTER :: p1 CHARACTER*(N),POINTER :: p3 p1 => p3 In this example, p1=>p3 is legal only if N==10, because there is a requirement on the well-defined type parameter of p2. 3. Nearby Problems 99-185r4 deliberately put undefined pointers into the same category as associated pointers (for the purposes of type parameter checking). On reflection, I believe that this is an obvious mistake (since their deferred parameters have no values to be checked). The obvious fix is to put them into the other category (i.e. treat them the same as disassociated pointers). I note that this has the unfortunate side-effect of preventing immediate runtime detection of type parameter value mismatch when the LHS (pointer) has a non-deferred parameter and the RHS (target) has a deferred parameter [because it is, in general, impossible to tell the difference between an associated pointer and an undefined pointer]. Apparently, the best a checking compiler can do is to set the pointer to a special "undefined" state when this happens and flag it later when it is used (if at all) - and give a slightly confusing error message, viz "use of undefined pointer or type parameter mismatch in earlier pointer assignment". If this situation is felt to be unacceptable there are four other possibilities when the LHS has a nondeferred type parameter corresponding to a deferred type parameter of the RHS: Option 0: Allow type parameter mismatch, but make the resultant pointer undefined. This is easy to describe in the standard but not very helpful for the user when he makes a mistake. Option 2: Disallow the pointer assignment when the RHS has undefined pointer association status. Option 3: Allow the pointer assignment only when the RHS is associated. Option 4: Disallow the pointer assignment always. This would not be an F95 compatibility problem because F95 did not have deferred type parameters, even for CHARACTER. The advantage here is that the user gets an error message at compile time if he makes a mistake. E.g. given the type declarations: CHARACTER*(10),POINTER :: P CHARACTER*(:),POINTER :: Q Then P=>Q is legal (0) Always, but P has undefined association status if LEN(Q)/=10. (1) Unless Q is associated with LEN(Q)/=10. (2) If Q is disassociated, or associated with LEN(Q)==10. (3) Only if Q is associated with LEN(Q)==10. (4) Never. Option 3 can emulate option 2 by coding: IF (ASSOCIATED(Q)) THEN P => Q ELSE NULLIFY(P) END IF Option 4 can emulate option 3 by coding IF (ASSOCIATED(Q)) THEN CALL PTRASGN(P,Q) ELSE NULLIFY(P) END IF ... SUBROUTINE PTRASGN(P,Q) CHARACTER*(*),POINTER :: P CHARACTER*(*),TARGET :: Q IF (LEN(P)/=LEN(Q)) STOP 'ERROR' P => Q END SUBROUTINE After discussion, subgroup recommended option (2) which gains most of the "checkability" with the least reduction in functionality. 4. Edits to 00-007 [137:22-26] Swap the two sentences of this paragraph, inverting the conditions; thus it reads "If is a disassociated pointer, all nondeferred type parameters of the declared type of that correspond to nondeferred type parameters of shall have the same values as the corresponding type parameters of . Otherwise, all nondeferred type parameters of the declared type of shall have the same values as the corresponding type parameters of ." {Improve the readability by changing the condition from "If not" to "If".} [137:26+] Insert new paragraph "If has nondeferred type parameters that correspond to deferred type parameters of , shall not be a pointer with undefined association status." {Move pointers with undefined association status to the forbidden category.} Always: [137:27-51] Delete. {Please.} ===END