Re: Copying a struct to a larger struct?



Netocrat <netocrat@xxxxxxxxxxx> writes:
> On Fri, 29 Jul 2005 00:56:03 +0400, Alexei A. Frounze wrote:
>
>> "Barry Schwarz" <schwarzb@xxxxxxxxx> wrote in message
>> news:g7uge1pv97iu2j9faooaguv3234gafc8ok@xxxxxxxxxx
>>> On 27 Jul 2005 12:32:08 -0700, "hermes_917@xxxxxxxxx"
>> ...
>>> There is no guarantee that the padding in the common part of the two
>>> structs is the same.
>>
>> If my memory serves me, the standard gurantees that.
>
> Perhaps you aren't using error correction on your memory. :)
>
> Barry is right, the standard doesn't guarantee it. The alignment of
> members within a struct is "implementation-defined" (I can't imagine why
> in practice a compiler would not pad them identically, but it isn't
> prohibited from padding differently).
>
> The only guarantees about member positions in structs are that no hole
> will occur at the beginning and that members will occupy increasing
> storage addresses.

But there is an additional guarantee. C99 6.5.2.3p5 says:

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.

There's no explicit guarantee *unless* the two structures are members
of the same union, but it's hard to imagine an implementation other
than the DS9K meeting this requirement for union members without
meeting it for all structures with common initial sequences.

> Padding also may be added at the end to ensure correct alignment for
> arrays of the struct (but this is again at the implementation's discretion
> - i.e. not of predictable / guaranteed / repeatable size).

>> But, I'd prefer to turn
>> that common part into a type used inside both structs. memcpy() will be able
>> to do bad things silently...
>
> memcpy() may do bad things if the common part is not padded identically,
> as well as if the smaller struct has padding at the end in space at which
> the larger struct has a member.

Yes, that can be a problem even given the additional guarantee above.
For example, given:

struct foo {
int x;
char y;
}

struct foobar {
int x;
char y;
char z;
}

it's effectively guaranteed that the x and y members will have the
same size and offset in both structures, but the z member of struct
foobar could very well occupy some of the padding of struct foo.

> You're right that your preferred solution is safe though.

Agreed.

--
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: Passing a callable object to Thread
    ... main.c:1: warning: struct has no members ... It's also common in C++ to treat a stand-alone object as an array of length 1. ... This is useful because any function defined to take a sequence of input can easily be given a single element instead: ...
    (comp.lang.python)
  • [PATCH 4/4] iop-adma: remove the workaround for missed interrupts on iop3xx
    ... @common: common dmaengine channel object members ... records the actual size of the descriptor slot pool ... struct list_head all_slots; ...
    (Linux-Kernel)
  • Re: Copying a struct to a larger struct?
    ... members within a struct is "implementation-defined" (I can't imagine why ... prohibited from padding differently). ... arrays of the struct (but this is again at the implementation's discretion ... > that common part into a type used inside both structs. ...
    (comp.lang.c)
  • [PATCH 01/20] tty: Introduce a tty_port common structure
    ... Every tty driver has its own concept of a port structure and because they all ... create commonality and then introduce common methods. ... struct signal_struct; ...
    (Linux-Kernel)
  • Re: Copying a struct to a larger struct?
    ... >> I think this would fail only if the compiler is such broken that it ... As Keith pointed out the standard provides a virtual guarantee that the ... the requirements for structs with common initial members to be padded ... >>> struct foobar { ...
    (comp.lang.c)