Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #8647

Re: offsetOf

From Eric Sosman <esosman@ieee-dot-org.invalid>
Newsgroups comp.lang.c
Subject Re: offsetOf
Date 2011-07-23 20:12 -0400
Organization A noiseless patient Spider
Message-ID <j0fo12$bd3$1@dont-email.me> (permalink)
References <pan.2011.07.23.20.54.51@mailinator.com>

Show all headers | View raw


On 7/23/2011 4:54 PM, Jack Boot wrote:
> Hello:
>
> This came up in a code review recently, I've never heard of it before,
> opinions welcome.
>
> There is a struct that looks a bit like this
>
> struct foo {
>    int a[10];
>    long b;
>    ...
> };
>
> Now I have a function that starts thusly:
>
> void
> bar ( struct foo * f )
> {
>    int * ip = (int *) foo;

     I guess you mean `f' here.

>    ...
> }
>
> The reviewer recommended, that for maximal portability I should replace
> this by:
>
> int * ip = ( (int *) ( ( (unsigned char *) foo ) + offsetOf(struct foo,
> a) ) );
>
> I've never seen this construction before, also I think type punning is
> inherently non-portable so I'm not sure how much this buys you.

     I don't think the reviewer is concerned about portability, because
the code as it stands is entirely portable: A pointer to a struct can
be converted to a pointer to its first element, and vice versa, and
nothing will go wrong.

     BUT what happens if somebody adds a new element `x' to the struct
and puts it before `a', so `a' is no longer the first element?  The
code becomes "portably incorrect," and the compiler is unlikely to warn
you about the error.

     If what you need is a pointer to the start of the `a' array, use

	int *ip = f->a;

This construct will find `a' no matter where it sits in the struct --
and has the further virtue that the the compiler will squawk if somebody
changes `a' to an array of `long' instead of `int'.

     If you also require (for some reason not apparent in the code as
shown) that `a' be first, you can

	assert(offsetof(struct foo, a) == 0);

... or use a "compile-time assertion" (GIYF) to make the same test.

-- 
Eric Sosman
esosman@ieee-dot-org.invalid

Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

offsetOf Jack Boot <jackboot@mailinator.com> - 2011-07-23 20:54 +0000
  Re: offsetOf Ian Collins <ian-news@hotmail.com> - 2011-07-24 09:05 +1200
  Re: offsetOf Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-07-23 23:03 +0100
    Re: offsetOf Jack Boot <jackboot@mailinator.com> - 2011-07-24 10:30 +0000
      Re: offsetOf Ian Collins <ian-news@hotmail.com> - 2011-07-24 22:41 +1200
      Re: offsetOf James Kuyper <jameskuyper@verizon.net> - 2011-07-24 08:36 -0400
      Re: offsetOf jt@toerring.de (Jens Thoms Toerring) - 2011-07-24 14:50 +0000
      Re: offsetOf Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2011-07-24 10:28 -0600
      Re: offsetOf Nobody <nobody@nowhere.com> - 2011-07-24 17:30 +0100
      Re: offsetOf gordonb.gkpc8@burditt.org (Gordon Burditt) - 2011-07-27 08:43 -0500
    Re: offsetOf Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-07-24 14:18 +0300
      Re: offsetOf Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-07-24 12:50 +0100
        Re: offsetOf Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-07-24 18:25 +0300
  Re: offsetOf Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-07-23 20:12 -0400
  Re: offsetOf "J. J. Farrell" <jjf@bcs.org.uk> - 2011-07-24 01:57 +0100

csiph-web