Re: void * pointer convert problem.



Christopher Benson-Manica <ataru@xxxxxxxxxxxxxxxxxxxxx> writes:
> nelu <tandauioan@xxxxxxxxx> wrote:
> (IANALL; apply salt granules as appropriate.)
>
>> struct s1 {
>> int id;
>> char *name;
>> int year;
>> };
>
>> struct s2 {
>> int id;
>> char *name;
>> int year;
>> time_t tstamp;
>> };
>
>> ...
>> void *p;
>> struct s2 b;
>> ...
>> p=&b;
>> ((struct s1 *)p)->year=2000;
>> ...
>
>> the last assignment may not be portable?
>
> That's my reading of 6.7.2.1 (12) of n869:
>
> "Within a structure object, the non-bit-field members and the units in
> which bit-fields reside have addresses that increase in the order in
> which they are declared. A pointer to a structure object, suitably
> converted, points to its initial member (or if that member is a bit-field,
> then to the unit in which it resides), and vice versa. There may be
> unnamed padding within a structure object, but not at its beginning."
>
> There is nothing that I can see which forbids an implementation from
> putting the year members at different offsets (due to the above
> mentioned unnamed padding), making the code you provided nonportable.
> Of course, non DS9K machines are unlikely to behave in such a
> manner...

But see also C99 6.5.2.3p5:

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 complete type of the union is visible. Two structures share a
_common initial sequence_ if corresponding members have compatible
types (and, for bit-fields, the same widths) for a sequence of one
or more initial members.

Strictly speaking, this guarantee applies only if the two structures
are members of the same union. If a compiler can prove to itself that
no such union exists in the program, it can theoretically use
different layouts for the common initial subsequences of two different
structure types. But it's difficult to imagine any non-DS9K
implementation going to the extra effort for no benefit I can think
of. The most straightforward way to comply with 6.5.2.3p5 is simply
to use layout rules that always guarantee the same layout for any
common initial subsequence.

If you're really concerned about conformance, you can declare (and not
bother to use) a union just to avoid the possibility, but I don't
think it's worth the effort.

--
Keith Thompson (The_Other_Keith) kst-u@xxxxxxx <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
.



Relevant Pages

  • Re: Pointer to "base" type - what does the Standard say about this?
    ... One such exception is to access equivalent initial members of structs ... that are union members. ... Don't make the base type a struct member, ... struct s {int i; const int ci;}; ...
    (comp.lang.c)
  • Re: type punning question...
    ... use of a union type is suggested. ... if a union contains several structures that share a common ... _common initial sequence_ if corresponding members have compatible ...
    (comp.std.c)
  • Re: copy unnamed union in struct
    ... access the members with or without the name as you please, ... should, probably, also be able to access the entire named union ... within the outer union. ...
    (comp.unix.programmer)
  • Re: union arrangement
    ... >> int x; ... > "union u".) ... It says that after you store a value into a union members, ... if the value of a member of a union object is used when the ...
    (comp.lang.c)
  • Re: My talk about Godel to the post-grads.
    ... IF a union of A and B is described only in terms of either A or B, then how can a union be a union of A AND B? ... exactly the property common to all and only the members of A and B, ... On the other hand, if the x's refer to any of the elements in either A or B, then you can make a case for saying "x is in A or x is in B" and make a union of A and B. I think you call it an intersection. ...
    (sci.logic)