rfg@lupine.ncd.com (Ron Guilmette) (03/04/91)
I'm having a discussion with a C implementor I know about the meaning of the following sentence from the ANSI C standard. (I think that this came from section 3.7.2, but I'm at home right now and I don't have the standard with me at the moment, so I'm not sure.) "If a translation unit contains one or more tenative definitions for an identifier, and the translation unit contains no external definition for that identifier, then the behavior is exactly as if the translation unit contains a file scope declaration of that identifier, with a composite type as of the end of the translation unit, with an initializer equal to zero." What exactly does this mean? My off-the-cuff interpretation of this statement was that if you had two files like: one.c: --------------------------------------------------------------------- int xxyyzz; --------------------------------------------------------------------- two.c: --------------------------------------------------------------------- int xxyyz; --------------------------------------------------------------------- and if you compiled them both and then tried to link them together into the same single program, that you should get an error at link time because there are two conflicting external *definitions* of the variable xxyyzz. This implementor I know disagrees with my interpretation. Who is right?
debra@wsinfo11.info.win.tue.nl (Paul de Bra) (03/05/91)
In article <4218@lupine.NCD.COM> rfg@lupine.ncd.com (Ron Guilmette) writes: >I'm having a discussion with a C implementor I know about the meaning of >the following sentence from the ANSI C standard... >[ description of tentative definition deleted ] >What exactly does this mean? My off-the-cuff interpretation of this >statement was that if you had two files like: >... [ example deleted ] >and if you compiled them both and then tried to link them together into >the same single program, that you should get an error at link time because >there are two conflicting external *definitions* of the variable xxyyzz. Nope, you are wrong. int xxyyzz; int xxyyzz; int xxyyzz; may be repeated as often as you like, as they are "tentative" definitions. you may have several (non-conflicting) tentative definitions of the same variable. A true (non-tentative) definition is one with initialization. you may write int xxyyzz=1; only once. if none of the (tentative) definitions has an initializer then the variable will be initialized with 0. Paul. (debra@win.tue.nl, debra@research.att.com)
rfg@NCD.COM (Ron Guilmette) (03/05/91)
In article <1807@svin02.info.win.tue.nl> debra@info.win.tue.nl writes: +In article <4218@lupine.NCD.COM> rfg@lupine.ncd.com (Ron Guilmette) writes: +>I'm having a discussion with a C implementor I know about the meaning of +>the following sentence from the ANSI C standard... +>[ description of tentative definition deleted ] +>What exactly does this mean? My off-the-cuff interpretation of this +>statement was that if you had two files like: +>... [ example deleted ] +>and if you compiled them both and then tried to link them together into +>the same single program, that you should get an error at link time because +>there are two conflicting external *definitions* of the variable xxyyzz. + +Nope, you are wrong. +int xxyyzz; int xxyyzz; int xxyyzz; +may be repeated as often as you like, as they are "tentative" definitions. +you may have several (non-conflicting) tentative definitions of the same +variable. +A true (non-tentative) definition is one with initialization. +you may write int xxyyzz=1; only once. +if none of the (tentative) definitions has an initializer then the +variable will be initialized with 0. Paul, I think that you missed my point entirely. I know that you are right that I can put: int xxyyzz; int xxyyzz; int xxyyzz; as many times as I like in ONE COMPILATION UNIT, but look again at the exact wording from 3.7.2: If a translation unit contains one or more tenative definitions for an identifier, and the translation unit contains no external definition for that identifier, then the behavior is EXACTLY as if the translation unit contains a file-scope declaration of that identifier... with an initializer equal to zero. Now that suggests to me that the following two "translation units" should be treated (by the compiler and assembler and linker) as being EXACTLY identical to one another: version1.c: -------------------------------------------------------------------- int xxyyz; int xxyyz; int xxyyz; -------------------------------------------------------------------- version2.c: -------------------------------------------------------------------- int xxyyz = 0; -------------------------------------------------------------------- Now if that is true, i.e. if the two translation units about are supposed to be treated EXACTLY alike, then when I link together the following two translation units: one.c: ------------------------------------------------------------------- int xxyyz; int xxyyz; int xxyyz; ------------------------------------------------------------------- two.c: ------------------------------------------------------------------- int xxyyz; int xxyyz; int xxyyz; ------------------------------------------------------------------- I should get EXACTLY the same number and types of errors (no more and no less) as I would get when I tried to like together the following two translation units: three.c: ------------------------------------------------------------------- int xxyyz = 0; ------------------------------------------------------------------- four.c: ------------------------------------------------------------------- int xxyyz = 0; ------------------------------------------------------------------- Now I'm willing to conceed that this may not have been what x3j11 intended, however that *is* the way 3.7.2 reads. You are suggesting that the true meaning of 3.7.2 is that if there is a whole set of tenative definitions for some symbol within a given set of linker input files, that the linker is supposed to create one (and only one) zero initializer for the whole set. I know that this is the way that things were traditionally done, but I certainly *don't* yet know if that was the intent of x3j11. I wish that somebody who was on x3j11 would tell me if that was the committee's intent or not. If it *was* the intent of x3j11 to do things in the traditional manner, I think that they should have worded 3.7.2 so that that would have been more clear. -- // Ron Guilmette - C++ Entomologist // Internet: rfg@ncd.com uucp: ...uunet!lupine!rfg // New motto: If it ain't broke, try using a bigger hammer.
sarima@tdatirv.UUCP (Stanley Friesen) (03/06/91)
In article <4218@lupine.NCD.COM> rfg@lupine.ncd.com (Ron Guilmette) writes: >I'm having a discussion with a C implementor I know about the meaning of >the following sentence from the ANSI C standard. > "If a translation unit contains one or more tenative definitions > for an identifier, and the translation unit contains no external > definition for that identifier, then the behavior is exactly as > if the translation unit contains a file scope declaration of that > identifier, with a composite type as of the end of the translation > unit, with an initializer equal to zero." > >What exactly does this mean? ... < Example consisting of two translation units (=files) deleted> >... if you compiled them both and then tried to link them together into >the same single program, that you should get an error at link time because >there are two conflicting external *definitions* of the variable xxyyzz. > >This implementor I know disagrees with my interpretation. > >Who is right? In essence you are right. The example you gave generates what ANSI calls 'undefined behavior'. This means that it is *not* a conforming C program. It also, generally, means that *any* behavior on the part of the system is acceptable. So, this *may* mean that the implementor's approach is a legal local *extension* to ANSI C. Of course any programs that depend on such an extension will not be portable. [It is a legal extension as long as the ANSI standard does not *require* a diagnostic for this error; I do not believe it does, so the extension is likely to be legal]. The whole matter is discussed in some detail in the rationale document. -- --------------- uunet!tdatirv!sarima (Stanley Friesen)
gwyn@smoke.brl.mil (Doug Gwyn) (03/11/91)
In article <4228@lupine.NCD.COM> rfg@NCD.COM (Ron Guilmette) writes: >If it *was* the intent of x3j11 to do things in the traditional manner, >I think that they should have worded 3.7.2 so that that would have been >more clear. "Tentative definition" is inherently a kludgy notion. However, it is irrelevant to the actual issue, which was whether or not a "relaxed ref/def" model could be used for external linkage by a conforming implementation. The answer is, yes, it is permitted, because programs that exploit this conforming extension do not have to violate a syntax rule or constraint to do so. However, such programs are definitely not strictly conforming programs.