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


Groups > comp.lang.c > #10883

Re: partial struct usage

From Phil Carmody <thefatphil_demunged@yahoo.co.uk>
Newsgroups comp.lang.c
Subject Re: partial struct usage
Date 2011-09-24 23:36 +0300
Organization A noiseless patient Spider
Message-ID <87vcshy8wu.fsf@bazspaz.fatphil.org> (permalink)
References <2011092410234736215-madler@alumnicaltechedu>

Show all headers | View raw


Mark Adler <madler@alumni.caltech.edu> writes:
> I have an internal structure with lots of stuff in it for controlling
> a data input operation.  E.g.:
> 
> struct data {
>     int have;
>     char *next;
>     ... lots more stuff to keep track of the state
> };
> 
> I would like to expose to the user (in the interface header file) only
> those first two elements, so that I can provide a macro (also in the
> header file) analogous to getc() to pull data that is readily
> available in the buffer, otherwise to call a function to go get more
> data.  But I want to hide the other stuff in the structure, in order
> to make sure that users of the library don't end up depending on
> things that I change later for internal use.  And for efficiency I
> don't want yet another layer of indirection pointing to another
> structure from within the exposed structure for the other stuff.
> 
> E.g.
> 
> struct ex {
>     int have;
>     char *next;
> };
> 
> #define getd(d) (((struct ex *)d)->have ? (((struct ex *)d)->have--,
> *(((struct ex *)d)->next)++) : getdf(d))
> 
> where d is a struct data *.
> 
> My question is: does the C standard provide an assurance that this
> will work?  I.e. that two different structures with identical sets of
> prefix elements will have those prefix elements layed out identically
> in memory so that casting one structure to the other will permit
> correct access to those prefix elements?

struct private {
        struct public {
                int have;
                char *next;
        } pub;
        other stuff;
}

let the clients see and pass around pointers to pub, and then either
use something like container_of() (which is not strictly portable), or
just rely on the address of the first member being the address of the
structure and just cast, to map that back to the struct private.

I wonder whether the union of structures with common initial sequences
might be the way of absolutely ensuring the fields are in the same
place:

union private {
        struct public {
                int have;
                char *next;
        } pub;
        struct priv {
                int have;
                char *next;
                other stuff;
        } priv;
};

The address of the union is guaranteed to be the same as the address
of pub and priv, so casting is safe, but in addition, have and next
will always be at the same relative address thanks to 6.5.2.3p6:

"""
6 One special guarantee is made in order to simplify the use of unions: if a union contains
  several structures that share a common initial sequence (see below), and if the union
  object currently contains one of these structures, it is permitted to inspect the common
  initial part of any of them anywhere that a declaration of the completed type of the union
  is visible. Two structures share a common initial sequence if corresponding members
  have compatible types (and, for bit-#elds, the same widths) for a sequence of one or more
  initial members.
"""


Phil

-- 
"Religion is what keeps the poor from murdering the rich."
-- Napoleon

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


Thread

partial struct usage Mark Adler <madler@alumni.caltech.edu> - 2011-09-24 10:23 -0700
  Re: partial struct usage Richard Damon <news.x.richarddamon@xoxy.net> - 2011-09-24 13:44 -0400
    Re: partial struct usage Tim Rentsch <txr@alumni.caltech.edu> - 2012-01-24 14:08 -0800
  Re: partial struct usage BGB <cr88192@hotmail.com> - 2011-09-24 11:08 -0700
  Re: partial struct usage Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-09-24 23:36 +0300
    Re: partial struct usage Mark Adler <madler@alumni.caltech.edu> - 2011-09-25 13:23 -0700
      Re: partial struct usage Gene <gene.ressler@gmail.com> - 2011-09-26 01:14 -0700
        Re: partial struct usage Richard Damon <news.x.richarddamon@xoxy.net> - 2011-09-26 12:37 -0400
          Re: partial struct usage Tim Rentsch <txr@alumni.caltech.edu> - 2012-01-24 16:04 -0800
        Re: partial struct usage Mark Adler <madler@alumni.caltech.edu> - 2011-09-26 18:52 -0700
          Re: partial struct usage Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-27 12:14 +0100
    Re: partial struct usage Tim Rentsch <txr@alumni.caltech.edu> - 2012-01-24 15:56 -0800
      Re: partial struct usage Shao Miller <sha0.miller@gmail.com> - 2012-01-24 23:30 -0500
        Re: partial struct usage Tim Rentsch <txr@alumni.caltech.edu> - 2012-01-31 16:11 -0800
          Re: partial struct usage Shao Miller <sha0.miller@gmail.com> - 2012-02-01 00:42 -0500
            Re: partial struct usage Tim Rentsch <txr@alumni.caltech.edu> - 2012-03-08 09:33 -0800
      Re: partial struct usage Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2012-02-12 02:10 +0200
        Re: partial struct usage Tim Rentsch <txr@alumni.caltech.edu> - 2012-03-08 09:38 -0800
          Re: partial struct usage Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2012-03-13 18:22 +0200
            Re: partial struct usage blp@cs.stanford.edu (Ben Pfaff) - 2012-03-13 09:55 -0700
  Re: partial struct usage Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-09-24 17:56 -0400

csiph-web