Article View: comp.std.c
Article #3006Re: Struct hack one last time (one last time)
From: Christopher R Volpe
Date: Sun, 03 Jan 1993 22:07
Date: Sun, 03 Jan 1993 22:07
76 lines
3068 bytes
3068 bytes
In article <1993Jan1.173852.26630@taumet.com>, steve@taumet.com (Steve Clamage) writes:
|> mjs@hubcap.clemson.edu (M. J. Saltzman) writes:
|>
|> >In a previous article (now expired at my site), I asked if the
|> >notorious "struct hack" was still conformant if the tail array in the
|> >struct was of type other than char. Since no-one ever replied, I'll
|> >ask one more time.
|>
|> I don't see that the type of the array makes any difference.
When dealing with malloced storage, it shouldn't, since such storage may be
used for an array of any type.
|>
|> I do believe that the hack is not strictly conforming, however, since
|> you would be using array indices outside the declared array bounds
|> (char or double makes no difference). The results of doing so are
It's not outside the bounds of the malloced array.
|> undefined. Nonetheless, I don't know of any implementations where this
|> would not work.
|>
|> I have thought of a plausible implementation where the struct hack
|> would fail, however.
|>
|> An implementation is allowed to add padding to the end of a struct.
Only for alignment purposes. The Standard is pretty clear on that.
|> Suppose that the implementation adds space to the end of each struct
|> type where it encodes information used for run-time error checking.
|> The struct hack would fail in this case, since it would overwrite data
|> used by the run-time system. I believe the implementation would still
|> be conforming, since we are in the arena of undefined behavior.
I disagree that we are in the area of undefined behavior, but regardless,
your implementation is non-conforming. Consider the following strictly
conforming program:
int main(void)
{
struct foo {
double field[1];
};
struct bar {
double field[2];
};
union both {
struct foo small;
struct bar big;
};
union both bothvar;
bothvar.big.field[1] = 1.0;
bothvar.small.field[0] = 0.0;
return 0;
}
Your hypothetical implementation would store padding at the end of each
structure type in which it would record the dimensions of the "field"
member of each struct. But then writing into bothvar.big.field[1] would
presumably overwrite this dimension information in bothvar.small, causing
strange bounds errors when trying to write into bothvar.small.field[0].
|> --
|>
|> Steve Clamage, TauMetric Corp, steve@taumet.com
--
==================
Chris Volpe
G.E. Corporate R&D
volpecr@crd.ge.com
Technical Details
Message-ID:
<1993Jan3.220729.9290@crd.ge.com>Path:
arc1-ca.pugleaf.net!sparky!uunet!crdgw1!rdsunx.crd.ge.com!bart!volpeReferences:
<1992Dec31.153931.7495@hubcap.clemson.edu> <1993Jan1.173852.26630@taumet.com>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!sparky!uunet!crdgw1!rdsunx.crd.ge.com!bart!volpe From: volpe@bart.NoSubdomain.NoDomain (Christopher R Volpe) Newsgroups: comp.std.c Subject: Re: Struct hack one last time (one last time) Message-ID: <1993Jan3.220729.9290@crd.ge.com> Date: 3 Jan 93 22:07:29 GMT References: <1992Dec31.153931.7495@hubcap.clemson.edu> <1993Jan1.173852.26630@taumet.com> Sender: volpe@bart (Christopher R Volpe) Reply-To: volpe@ausable.crd.ge.com Organization: GE Corporate Research & Development Lines: 76 Nntp-Posting-Host: bart.crd.ge.com