Newsgroups: comp.std.c Path: utzoo!utgpu!jarvis.csri.toronto.edu!dgp.toronto.edu!hugh From: hugh@dgp.toronto.edu (D. Hugh Redelmeier) Subject: Re: Interpretation needed Re: function prototypes (LONG) Message-ID: <1989Jul12.014327.15180@jarvis.csri.toronto.edu> Organization: University of Toronto, CSRI References: <12570014@hpclscu.HP.COM> Shankar Unni raised an interesting question about function prototypes in <12570014@hpclscu.HP.COM>. Dave Prosser (in <1008@cbnewsl.ATT.COM>) and Doug Gwyn (in <10494@smoke.BRL.MIL>) answer his question by explaining how the language of the standard is to be read. Although I hadn't read it this way, they are clearly right. I think that this interpretation leads to an internal inconsistency in the standard. I will attempt to explain this with reference to one of Shankar's examples: | (a) int func1 (const int); | int func1 (int p) { /* can "p" be modified here? */ } The language in 3.5.4.3 (page 69, line 24) (as explicated by dfp and gwyn) assures us that these declarations are compatible: | (... For each | parameter declared with a qualified type, its type for these comparisons | is the unqualified version of its declared type.) Now, the question arises: what is the type of func1? 3.1.2.6 (page 26, line 19) says: | For an identifier with external or internal linkage declared in | the same scope as another declaration for that identifier, the type | of the identifier becomes the composite type. We can refine our earlier question to: what is the composite type of "int (const int)" and "int (int)"? First, let's find out if there is a composite type for these. We are assured that there is by 3.1.2.6 (page 26, line 11): | A "composite type" can be constructed from two types that are | compatible; it is a type that is compatible with both of the two | types and satisfies the following conditions: | ... | - If both types are function types with parameter type lists, the | type of each parameter in the composite parameter type list is the | composite type of the corresponding parameters. But look: this implies that in our case, there must be a composite type for the parameter types "const int" and "int". I don't see how there can be, since they are clearly NOT compatible. Thus we have an inconsistency. Dave Prosser (if I understand what he is saying) thinks not: | There is a misunderstanding here. The parenthetical sentences [in | 3.5.4.3, partially quoted above -- DHR] are not differences in type | that participate in producing a (possibly different) composite | type. Many people also seem to believe that type qualifiers have | this sort of connection with composite types, for whatever reason. | These sentences state that these "rewrites" of the parameter types | are part of the type comparison: types that are the same after the | rewrite are the same. I think he is wrong by his own reasoning: the parenthetical comments only apply to this paragraph, and not the one describing the composite type. Besides, "same" is not the same as "compatible". The parenthetical comment affects the comparison operation, not the types themselves. Now that I look at it, I think that the same problem arises with function and array parameters. This is because the rewriting to pointer types is only mandated for function definitions, and not function declarators in general (see 3.7.1 page 83 line 23). I think that the obvious fix for this problem is to have the rewrite apply to all function declarators (as well as old style definitions). Perhaps better would have been to make this form of parameter illegal for prototyped functions, but that is another topic. How this inconsistency is resolved also affects the answer to Shankar's additional question, /* can "p" be modified here? */. This does not seem to me to be an easy question. If you have an answer, then what about the following variant of his question? | (a) int func1 (int); | int func1 (const int p) { /* can "p" be modified here? */ } If the composite type of func1 is "int (int)", then I would think that p can be modified in the body, even though it is declared const! Hugh Redelmeier {utcsri, yunexus, uunet!attcan!utzoo, hcr}!redvax!hugh When all else fails: hugh@csri.toronto.edu +1 416 482-8253