This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c/16622] [C99] extern inline is handled wrong in C99 mode


------- Additional Comments From hozelda at yahoo dot com  2004-08-08 21:51 -------
(In reply to comment #5) 
> Subject: Re:  [C99] extern inline is handled wrong in C99 mode 
>  
> On Sat, 7 Aug 2004, hozelda at yahoo dot com wrote: 
>  
> > By 6.9 and 6.9.1, every translation unit has exactly one or zero definition for 
a  
> > function. This means that the same translation unit cannot have both an 
inline  
> > and an external def.  
>  
> I don't see how you deduce this.  I agree it's the intent, but I see 
> nothing in the text of the standard that specifically prohibits having 
> both inline and external definitions in a translation unit, just the 
> presumption in 6.7.4#6 that there is just one definition of the function 
> in the TU.  I mentioned this in an aside to my pre-DR#2 that I sent to the 
> gcc list some time ago <http://www.srcf.ucam.org/~jsm28/gcc/pre-dr-2.txt>. 
>  
> This would also be one of the incompatibilities between C99 and gnu89, as 
> GCC has allowed both inline and external definitions while the intent of 
> C99 seems to be not to allow them.  Thus, one more potential problem to 
> fix in glibc should C99 inline be implemented in GCC. 
>  
 
I was a little sloppy to extend 6.9xxx to inline definitions. [The message posted 
was also a learning process for me and I didn't re-evaluate some held 
assumptions as much as I should have.] 
 
6.7.4#6 says, "an inline definition ... does not forbid an external definition in 
__another__ translation unit." 
 
6.7.4#8 says, "Because cels [which has an inline definition] has external 
linkage and is referenced, an external definition has to appear in another 
translation unit...." 
 
#6 does not place any requirements; the wording simply seems to suggest that 
such a requirement already existed. 
 
#8 doesn't place a requirement either but the wording is as if such a 
requirement was in place so that its conclusion can be drawn. I would say that 
#8 by itself would mean that inline definitions and external definitions (for same 
identifier) cannot co-exhist in the same translation unit (if perhaps in need of 
rewording as a rule elsewhere), except that it seems to be an extension of the 
#7 Example, which would then not be normative. 
 
My guess is that the intention is to have at most either one ID or else one ED 
per t-u. If that was the intention, then there appears to be a defect in the 
Standard, as it cannot be derived from any normative portion, at least as I read 
6.9/6.9.1 and 6.7.4. If the intention, instead, is to allow >1 ID and possibly an 
ED (per t-u), then the Standard seems ok except that the wording (of the 
examples #7/#8) should probably eventually be fixed. 
 
Thus I think you are completely right if the above is all that there is to it. 
 
 
The link you posted is very interesting (well, if one is looking to get to the 
bottom of things). I'll spend more time with it later. I do know that I thought 
originally that "prototype" was not evolved/defined as well as it should have 
been, but eventually I came to just accept certain understandings of it.. I'll revisit 
that, I guess, especially since you seem to have pinpointed some precise 
items. 
 
 
> > *** [Using this understanding of "reference" ...] Within a function such as 'g'  
> > (inline def/ exte link), gcc would need to verify the linkage of every identifier 
it  
> > came across no matter how deeply nested (within a declaration or within a  
> > statement). This is right, no?  
>  
> Including those inside sizeof.  I don't think this is a tricky 
> interpretative issue.  If, in the inline definition, the identifier is 
> used (in the name space of ordinary identifiers) while the internal 
> linkage declaration is in scope, or declared as extern while that 
> declaration is in scope (so linking to the previous internal linkage 
> declaration), this is a constraint violation.  If it is used in another 
> namespace, or redeclared as an identifier with no linkage, there is no 
> problem.  If it is declared with external linkage in a scope where the 
> internal linkage declaration is hidden, this is compile-time undefined 
> behavior and an error is permitted though not required. 
>  
>  
 
One person's garbage is another's treasure.. or something like that. Ok, that 
paragraph you quoted and a few other things were last minute additions after 
about a week of letting the message sit. Since I don't have that much 
experience with compiler internals, it just wasn't something I had thought about 
before so it seemed like a Eureka momment (I was debating over the meaning 
of "reference" so ...) .. it's as if "oh, let's go back and add code (a fix) so that 
every single ident is rechecked for ...." Anyway, it was "tricky" for me at that 
point in time, and also there probably is nothing there that excludes sizeof or 
any other case. 
 
In general, all of these (constant) sizeof rule exceptions are a little annoying in 
that they are scattered around when perhaps maybe a new concept should be 
introduced (unevaluable expression.. or something like that [(aside) I think the 
Java Lang std uses a similar concept and defines a lot of rules for it]). 
Especially since in some cases something more general than sizeof is evoked 
(with perhaps a footnote mentioning sizeof)... anyway, these are just some 
thoughts. 
 
I don't want to comment much more on what I said near the end because I 
should be willing to provide specific code first, to make things concrete. 
 
 
I have an unrelated question. 
  void *h1=0; 
  int (*h2)(int)=0, (*h3)(int)=0; 
  h2=h1;  //should not be allowed but gcc 3.2.2 didn't complain 
  h1=h3;  //should not be allowed .... 
 
Is this legit material for a bug report (ie, is the "should not" in the comments 
correct)? [I compiled the example with c99 but not with pedantic] 
 
I don't think you can perform the 2 assignments above without a cast (and even 
then, guarantees from #6.3.2.3 may be lost (eg, see #7 and #8 as a pattern)). 
6.5.16.1#1 is a constraint (and "one of the following shall hold" would not be 
satisfied), and I don't think void* is compatible with functype* and I don't think 
functype can ever be incomplete. 
 
There may be gaps in the std or maybe not, so unless you readily agree or 
disagree, I would need to reread around and come up with specific references. 
 
 
A quick question: is there a way to receive auto emails of bug reports one has 
participated in (by commenting)? I didn't get jsm's comment as an email of any 
sort. I checked the pref->email section of my account, but I could not find the 
option. 
 
 

-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=16622


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]