Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Newsgroups | comp.lang.c |
| Subject | Re: Aliasing through a union pointer |
| Date | 2015-11-23 11:43 -0500 |
| Organization | A noiseless patient Spider |
| Message-ID | <n2vfjp$e1t$1@dont-email.me> (permalink) |
| References | <n2vdrr$6c5$1@dont-email.me> |
On 11/23/2015 11:14 AM, Ian Pilcher wrote:
> I am working with a "header" struct, all of whose members are
> uint64_t's. I would like to treat the struct as an array of
> uint64_t when calculating a checksum, byte swapping for endian
> compatibility, etc.
>
> Is casting a pointer to the struct to a pointer to union a safe
> way to do this (from an aliasing point of view)? Is there a
> better way to do it?
>
> For example:
>
> struct header {
> uint64_t magic;
> uint64_t version;
> uint64_t size;
> uint64_t uuid_lo;
> uint64_t uuid_hi;
> uint64_t type;
> uint64_t offset;
> uint64_t size;
> uint64_t cksum;
> };
>
> #define HEADER_ARRAY_SIZE (sizeof(struct header) / sizeof(uint64_t))
>
> union header_u {
> struct header h;
> uint64_t u[HEADER_ARRAY_SIZE];
> };
>
> /* Broken if the struct has any padding */
> uint64_t naive_cksum(struct header *const hdr)
> {
> union header_u *const hu = (union header_u *)hdr;
>
> uint64_t save, sum;
> unsigned i;
>
>
> save = hu->h.cksum;
> hu->h.cksum = 0;
>
> for (sum = 0, i = 0; i < HEADER_ARRAY_SIZE; ++i)
> sum += hu->u[i];
>
> hu->h.cksum = save;
>
> return sum;
> }
The first difficulty that occurs to me is one that's already
occurred to you: You're screwed if the struct has any padding,
either interstitial or at the end. That seems fairly unlikely,
but is permitted by the language. As a "Just In Case" measure,
you might try asserting that
offsetof(struct header, cksum) + sizeof(uint64_t)
== sizeof(struct header)
... which would detect the presence of padding.
The next thing I think of is alignment: What if the alignment
of the union type is stricter than that of the struct? If anything
this is even less likely than the presence of padding, but I still
believe it's permitted. If it happens, then the pointer conversion
at the start of the naive_cksum() function could go awry.
A more serious matter -- an Actual Problem, I believe -- is
the modification (twice!) of an object referenced through a const-
qualified pointer. (Didn't your compiler complain?) You'd better
find another way to leave the stored checksum out of the computation.
In naive_cksum() you could just initialize `sum' to `-hu->h.cksum'
instead of to zero, but you'd need to be cagier with CRC's or other
less easily-inverted algorithms (where supplying a zero `cksum' might
not be appropriate, either).
... or you could assume that `cksum' is always the final element,
and stop the loop one iteration sooner. Or you could use offsetof
to determine which array index corresponds to `cksum', and skip that
one. Or you could ditch `const'.
It seems to me that once you've ensured there's no padding --
which you ought to do in any case -- the union doesn't buy you much:
Just cast `hdr' to a `uint64_t*' and blaze away. This also has the
virtue of avoiding the (highly unlikely) alignment problem, because
the struct alignment is at least good enough for a uint64_t.
--
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM
Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
Aliasing through a union pointer Ian Pilcher <arequipeno@gmail.com> - 2015-11-23 10:14 -0600
Re: Aliasing through a union pointer Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-11-23 11:43 -0500
Re: Aliasing through a union pointer Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-11-23 11:49 -0500
Re: Aliasing through a union pointer Ian Pilcher <arequipeno@gmail.com> - 2015-11-23 13:22 -0600
Re: Aliasing through a union pointer Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-11-23 14:38 -0500
Re: Aliasing through a union pointer Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-25 10:38 -0800
Re: Aliasing through a union pointer Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-11-25 14:17 -0500
Re: Aliasing through a union pointer Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-27 13:16 -0800
Re: Aliasing through a union pointer David Brown <david.brown@hesbynett.no> - 2015-11-23 21:46 +0100
Re: Aliasing through a union pointer Jorgen Grahn <grahn+nntp@snipabacken.se> - 2015-11-23 22:20 +0000
Re: Aliasing through a union pointer Stephen Sprunk <stephen@sprunk.org> - 2015-11-23 16:52 -0600
Re: Aliasing through a union pointer Jorgen Grahn <grahn+nntp@snipabacken.se> - 2015-11-23 23:10 +0000
Re: Aliasing through a union pointer Stephen Sprunk <stephen@sprunk.org> - 2015-11-23 19:05 -0600
Re: Aliasing through a union pointer Nick Bowler <nbowler@draconx.ca> - 2015-11-23 22:51 +0000
Re: Aliasing through a union pointer Keith Thompson <kst-u@mib.org> - 2015-11-23 15:49 -0800
Re: Aliasing through a union pointer supercat@casperkitty.com - 2015-11-23 16:01 -0800
Re: Aliasing through a union pointer David Brown <david.brown@hesbynett.no> - 2015-11-24 09:55 +0100
Re: Aliasing through a union pointer Jorgen Grahn <grahn+nntp@snipabacken.se> - 2015-11-24 14:29 +0000
Re: Aliasing through a union pointer David Brown <david.brown@hesbynett.no> - 2015-11-24 22:58 +0100
Re: Aliasing through a union pointer Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-11-24 17:30 -0500
Re: Aliasing through a union pointer supercat@casperkitty.com - 2015-11-24 15:27 -0800
Re: Aliasing through a union pointer Ian Collins <ian-news@hotmail.com> - 2015-11-25 12:57 +1300
Re: Aliasing through a union pointer supercat@casperkitty.com - 2015-11-24 16:31 -0800
Re: Aliasing through a union pointer Ian Collins <ian-news@hotmail.com> - 2015-11-25 18:28 +1300
Re: Aliasing through a union pointer supercat@casperkitty.com - 2015-11-25 06:54 -0800
Re: Aliasing through a union pointer Ian Collins <ian-news@hotmail.com> - 2015-11-26 08:59 +1300
Re: Aliasing through a union pointer supercat@casperkitty.com - 2015-11-25 13:01 -0800
Re: Aliasing through a union pointer Ian Collins <ian-news@hotmail.com> - 2015-11-26 12:58 +1300
Re: Aliasing through a union pointer supercat@casperkitty.com - 2015-11-25 16:44 -0800
Re: Aliasing through a union pointer Ian Collins <ian-news@hotmail.com> - 2015-11-26 14:12 +1300
Re: Aliasing through a union pointer supercat@casperkitty.com - 2015-11-25 21:34 -0800
Re: Aliasing through a union pointer Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-11-25 21:55 -0800
Re: Aliasing through a union pointer Ian Collins <ian-news@hotmail.com> - 2015-11-26 20:51 +1300
Re: Aliasing through a union pointer supercat@casperkitty.com - 2015-11-26 11:39 -0800
Re: Aliasing through a union pointer Jorgen Grahn <grahn+nntp@snipabacken.se> - 2015-11-26 00:06 +0000
Re: Aliasing through a union pointer Keith Thompson <kst-u@mib.org> - 2015-11-24 11:51 -0800
Re: Aliasing through a union pointer supercat@casperkitty.com - 2015-11-24 12:20 -0800
Re: Aliasing through a union pointer Keith Thompson <kst-u@mib.org> - 2015-11-24 21:52 -0800
Re: Aliasing through a union pointer supercat@casperkitty.com - 2015-11-25 08:30 -0800
Re: Aliasing through a union pointer David Brown <david.brown@hesbynett.no> - 2015-11-24 23:04 +0100
Re: Aliasing through a union pointer Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-25 10:10 -0800
Re: Aliasing through a union pointer Richard Damon <Richard@Damon-Family.org> - 2015-11-25 11:02 -0800
Re: Aliasing through a union pointer Philip Lantz <prl@canterey.us> - 2015-11-26 13:06 -0800
Re: Aliasing through a union pointer Richard Damon <Richard@Damon-Family.org> - 2015-11-26 13:09 -0800
Re: Aliasing through a union pointer Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-27 13:08 -0800
csiph-web