This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c/16622] [C99] extern inline is handled wrong in C99 mode
- From: "hozelda at yahoo dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 8 Aug 2004 21:51:13 -0000
- Subject: [Bug c/16622] [C99] extern inline is handled wrong in C99 mode
- References: <20040718224725.16622.pinskia@gcc.gnu.org>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- 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