eggert@twinsun.com (Paul Eggert) (11/28/89)
Norman Diamond writes:
... the standard does not limit an identifier with external linkage to
having only one initialization (when the identifier is never used in an
expression).
Doug Gwyn replies:
... I have not been convinced that the Standard has a problem in this
area. Section 2.1.2 makes the initialization model pretty clear, and
combined with the obvious notion that a variable holds a single value
at a time it precludes multiple simultaneous initializers.
2.1.2 (Execution environments) does not really resolve this issue because 2.1.2
doesn't have to be combined with the ``obvious notion''. 2.1.2 says:
All objects in static storage shall be _initialized_ (set to their
initial values) before program startup. The manner and timing of such
initialization are otherwise unspecified.
It's reasonable to interpret this to mean that multiple initial values are
allowed, and that the multiple initializations are performed, but that because
the manner and timing of initialization is unspecified, the ``winning'' initial
value is unspecified.
Besides, 2.1.2 is a red herring here. The real problem is a bug in the wording
in 3.7 (External definitions). This bug applies to both objects and functions,
so it also permits multiple definitions of unused functions with external
linkage. HP's Walter Murray pointed this out in a news posting, as did Twin
Sun's Mike Coleman when he originally brought this problem to my attention.
Thus, the following program is strictly conforming even though it's
``obviously'' wrong:
int F(){return 0;}
int F(){return 1;}
int V = 0;
int V = 1;
int main(){return 0;}
Even assuming that the above quote from 2.1.2 prohibited the two Vs,
it wouldn't address the problem of the two Fs.
steve@groucho.ucar.edu (Steve Emmerson) (11/28/89)
eggert@twinsun.com (Paul Eggert) writes: >Thus, the following program is strictly conforming even though it's >``obviously'' wrong: > int F(){return 0;} > int F(){return 1;} > int V = 0; > int V = 1; > int main(){return 0;} That's right. pANS C -- just like the old C -- still allows you to write nonsense programs. But, ah..., why would you want to? ----- Steve Emmerson steve@unidata.ucar.edu
gwyn@smoke.BRL.MIL (Doug Gwyn) (11/29/89)
In article <57@looney.twinsun.com> eggert@twinsun.com (Paul Eggert) writes: >The real problem is a bug in the wording in 3.7 (External definitions). >This bug applies to both objects and functions, so it also permits multiple >definitions of unused functions with external linkage. HP's Walter Murray >pointed this out in a news posting, as did Twin Sun's Mike Coleman when he >originally brought this problem to my attention. Thus, the following >program is strictly conforming even though it's ``obviously'' wrong: > int F(){return 0;} > int F(){return 1;} > int V = 0; > int V = 1; > int main(){return 0;} >Even assuming that the above quote from 2.1.2 prohibited the two Vs, >it wouldn't address the problem of the two Fs. As indicated by the footnote, this wording ("if ... is used in an expression") was designed to permit ZERO definitions for unused objects and functions, to support existing practice. (Some compilers cannot reasonably generate references to unused, albeit declared, external names.) While agreeing that the wording in 3.7 would have been better if it had explicitly prohibited MULTIPLE definitions for unused objects or functions, I still don't think that there is a large practical problem in correctly implementing this, because throughout the Standard the notion that a particular named external function has A definition, not a class of definitions, is quite obvious. And when a definition has no use it really doesn't matter whether or not it is multiple, apart from the question of how to implement this so that "strictly conforming" code that abuses this loophole will be accepted. My suggestion is to generate a warning (not an official diagnostic) for the second definition within a translation unit, and generate code for only the first definition. Inter-translation unit multiple definitions are handled the usual way (typically by the linker). That technique should be standard conforming.
eggert@twinsun.com (Paul Eggert) (11/30/89)
Doug Gwyn writes:
My suggestion is to generate a warning (not an official diagnostic) for
the second definition within a translation unit, and generate code for
only the first definition. Inter-translation unit multiple definitions
are handled the usual way (typically by the linker). That technique
should be standard conforming.
Does this suggestion mean that the following strictly conforming program with
two translation units should link correctly, albeit perhaps with warnings?
x.c:
int F(){return 0;}
int G(int i){return i;}
y.c:
int F(){return 1;}
int G(int);
int main() {return G(0);}
Won't most linkers flatly refuse to link this program
because F is defined twice?
gwyn@smoke.BRL.MIL (Doug Gwyn) (12/01/89)
In article <58@looney.twinsun.com> eggert@twinsun.com (Paul Eggert) writes: >Doug Gwyn writes: >>My suggestion is to generate a warning (not an official diagnostic) for >>the second definition within a translation unit, and generate code for >>only the first definition. >Does this suggestion mean that the following strictly conforming program with >two translation units should link correctly, albeit perhaps with warnings? [omitted to save space] >Won't most linkers flatly refuse to link this program >because F is defined twice? Oops. Your argument is evidence that multiple external definitions for the same identifier could not have been the Committee's intent (since that linker model is the most commonly encountered one). Therefore the lack of a clear prohibition against multiple definitions (amongst the entire set of modules constituting a program, not just confined to a single translation unit) must really have been an oversight. In fact, I recall something like that constraint in earlier drafts, so it probably got lost in the editing that occurred in this area in response to public review comments on external linkage. One can still fall back on the ANDIPS and the obvious model of an object/function as having only one definition implied by phraseology scattered throughout the Standard to back the "no more than one definition" interpretation. However, this one really does need to receive an official X3J11 interpretation ruling, since it potentially impacts implementations in a major way. (Having to support multiple external definitions would require linker changes in many environments, and that was definitely not the committee's intention.)