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


Groups > comp.lang.c > #91921 > unrolled thread

Structure packing & padding: what sizeof reports? Any caveats?

Started byTest <test@.nil.invalid.com>
First post2016-08-08 10:15 +0300
Last post2016-08-08 11:17 -0400
Articles 8 — 7 participants

Back to article view | Back to comp.lang.c


Contents

  Structure packing & padding: what sizeof reports? Any caveats? Test <test@.nil.invalid.com> - 2016-08-08 10:15 +0300
    Re: Structure packing & padding: what sizeof reports? Any caveats? Ian Collins <ian-news@hotmail.com> - 2016-08-08 19:36 +1200
      Re: Structure packing & padding: what sizeof reports? Any caveats? Richard Heathfield <rjh@cpax.org.uk> - 2016-08-08 08:52 +0100
    Re: Structure packing & padding: what sizeof reports? Any caveats? Richard Heathfield <rjh@cpax.org.uk> - 2016-08-08 08:51 +0100
      Re: Structure packing & padding: what sizeof reports? Any caveats? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-08-08 11:29 +0100
      Re: Structure packing & padding: what sizeof reports? Any caveats? Keith Thompson <kst-u@mib.org> - 2016-08-08 08:56 -0700
    Re: Structure packing & padding: what sizeof reports? Any caveats? Barry Schwarz <schwarzb@dqel.com> - 2016-08-08 01:37 -0700
    Re: Structure packing & padding: what sizeof reports? Any caveats? James Kuyper <jameskuyper@verizon.net> - 2016-08-08 11:17 -0400

#91921 — Structure packing & padding: what sizeof reports? Any caveats?

FromTest <test@.nil.invalid.com>
Date2016-08-08 10:15 +0300
SubjectStructure packing & padding: what sizeof reports? Any caveats?
Message-ID<inbgqb9dm89a0el2m4sh8ntqb8541r7miu@4ax.com>
I am saving structures and variables to a string. For example:

..
struct MixedData 
{
    char Data1;
    int num1; 
    short num2;
};

...
blah blah
..

char mystr[256];
int i;
struct MixedData whatever;

...
blah blah
..

i=55;
whatever.num1=60
memcpy(&mystr[4],&whatever,sizeof(struct MixedData));

...
blah blah
..
memcpy(&whatever,&mystr[4],sizeof(struct MixedData));
// i should be now 60

Is above OK or should I worry about if my structed is padded or packed, ie. will
sizeof() report correct value.
I am using GCC

[toc] | [next] | [standalone]


#91922

FromIan Collins <ian-news@hotmail.com>
Date2016-08-08 19:36 +1200
Message-ID<e0qr3cFfpjhU1@mid.individual.net>
In reply to#91921
On 08/ 8/16 07:15 PM, Test wrote:
> I am saving structures and variables to a string. For example:
>
> ...
> struct MixedData
> {
>      char Data1;
>      int num1;
>      short num2;
> };
>
> ....
> blah blah
> ...
>
> char mystr[256];
> int i;
> struct MixedData whatever;
>
> ....
> blah blah
> ...
>
> i=55;
> whatever.num1=60
> memcpy(&mystr[4],&whatever,sizeof(struct MixedData));
>
> ....
> blah blah
> ...
> memcpy(&whatever,&mystr[4],sizeof(struct MixedData));
> // i should be now 60
>
> Is above OK or should I worry about if my structed is padded or packed, ie. will
> sizeof() report correct value.

The value returned by sizeof includes any packing bytes.

-- 
Ian

[toc] | [prev] | [next] | [standalone]


#91926

FromRichard Heathfield <rjh@cpax.org.uk>
Date2016-08-08 08:52 +0100
Message-ID<no9dn4$afe$2@dont-email.me>
In reply to#91922
On 08/08/16 08:36, Ian Collins wrote:
<snip>
>
> The value returned by sizeof includes any packing bytes.

ITYM "padding bytes".

-- 
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

[toc] | [prev] | [next] | [standalone]


#91925

FromRichard Heathfield <rjh@cpax.org.uk>
Date2016-08-08 08:51 +0100
Message-ID<no9dlh$afe$1@dont-email.me>
In reply to#91921
On 08/08/16 08:15, Test wrote:
> I am saving structures and variables to a string. For example:
>
> ..
> struct MixedData
> {
>     char Data1;
>     int num1;
>     short num2;
> };
>
> ...
> blah blah
> ..
>
> char mystr[256];
> int i;
> struct MixedData whatever;
>
> ...
> blah blah
> ..
>
> i=55;

What's this for?

> whatever.num1=60

You forgot the semicolon, so you're going to get a diagnostic message 
from your compiler. More importantly, whatever.Data1 and whatever.num2 
remain indeterminate.

> memcpy(&mystr[4],&whatever,sizeof(struct MixedData));

memcpy treats every byte as if it were an unsigned char, so you'll get 
away this this copy operation, but from this point on, the content of 
mystr must be handled very carefully, as much of that content has an 
indeterminate value.

> memcpy(&whatever,&mystr[4],sizeof(struct MixedData));
> // i should be now 60
>
> Is above OK

It's horrible, and it isn't guaranteed to work. Your hard-coded 4 is one 
of your problems, since it assumes that there are exactly three padding 
bytes after the Data1 member.

> or should I worry about if my structed is padded or packed,

Padding is legal (but not required) after any structure member, and 
there is no upper limit on the number of bytes of padding that can be used.

> ie. will
> sizeof() report correct value.

sizeof will always report the number of bytes required to store its 
operand, and that number will always be correct, given a correct 
program. (In other words, if you stick to the rules, so will the 
compiler.) But that size may well include padding bytes.

> I am using GCC

If that matters, you need to be asking in a gcc group. And if it doesn't 
matter, it doesn't matter.

-- 
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

[toc] | [prev] | [next] | [standalone]


#91939

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-08-08 11:29 +0100
Message-ID<877fbrlfj1.fsf@bsb.me.uk>
In reply to#91925
Richard Heathfield <rjh@cpax.org.uk> writes:

> On 08/08/16 08:15, Test wrote:
>> I am saving structures and variables to a string. For example:
>> ..
>> struct MixedData
>> {
>>     char Data1;
>>     int num1;
>>     short num2;
>> };
<snip>
>> char mystr[256];
>> struct MixedData whatever;
<snip>
>> memcpy(&mystr[4],&whatever,sizeof(struct MixedData));
<snip>
>> memcpy(&whatever,&mystr[4],sizeof(struct MixedData));

To the OP: I find

  memcpy(dest, &whatever, sizeof whatever);

to be more obviously correct.  There is no need to check that the type
used in the sizeof is that of declared object 'whatever'.  It's a case
of directly writing what you mean rather than something that works.

>> Is above OK
>
> It's horrible, and it isn't guaranteed to work. Your hard-coded 4 is
> one of your problems, since it assumes that there are exactly three
> padding bytes after the Data1 member.

I don't think it does.  &mystr[4] is simply where Test wants to put the
data.  Yes, the 4 is still a hard-coded number, and that might be a
problem for other reasons, but I don't think it's got anything to do
with padding assumptions.

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#91964

FromKeith Thompson <kst-u@mib.org>
Date2016-08-08 08:56 -0700
Message-ID<ln60rbw8xr.fsf@kst-u.example.com>
In reply to#91925
Richard Heathfield <rjh@cpax.org.uk> writes:
> On 08/08/16 08:15, Test wrote:
[...]
>> I am using GCC
>
> If that matters, you need to be asking in a gcc group. And if it doesn't 
> matter, it doesn't matter.

True -- but this is a great place to ask whether it matters or not.
Mentioning which compiler you're using doesn't hurt; it's better than
leaving that information out and later finding that it's relevant.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#91929

FromBarry Schwarz <schwarzb@dqel.com>
Date2016-08-08 01:37 -0700
Message-ID<iuggqbpg1hc2djseq4an4qt38vrsljat7l@4ax.com>
In reply to#91921
On Mon, 08 Aug 2016 10:15:24 +0300, Test <test@.nil.invalid.com>
wrote:

>I am saving structures and variables to a string. For example:

Actually, you are saving the data in an array of char.  There is no
guarantee that any part of the array is a string (which would require
proper termination).  It is also possible for the array to contain
multiple strings.  It all depends on the values of the objects being
copied to the array.

>struct MixedData 
>{
>    char Data1;
>    int num1; 
>    short num2;
>};
>
>...
>blah blah
>..
>
>char mystr[256];
>int i;
>struct MixedData whatever;
>
>...
>blah blah
>..
>
>i=55;
>whatever.num1=60
>memcpy(&mystr[4],&whatever,sizeof(struct MixedData));
>
>...
>blah blah
>..
>memcpy(&whatever,&mystr[4],sizeof(struct MixedData));
>// i should be now 60
>
>Is above OK or should I worry about if my structed is padded or packed, ie. will
>sizeof() report correct value.
>I am using GCC

-- 
Remove del for email

[toc] | [prev] | [next] | [standalone]


#91959

FromJames Kuyper <jameskuyper@verizon.net>
Date2016-08-08 11:17 -0400
Message-ID<noa7pf$tnp$1@dont-email.me>
In reply to#91921
On 08/08/2016 03:15 AM, Test wrote:
> I am saving structures and variables to a string. For example:
> 
> ..
> struct MixedData 
> {
>     char Data1;
>     int num1; 
>     short num2;
> };
> 
> ...
> blah blah
> ..
> 
> char mystr[256];
> int i;
> struct MixedData whatever;
> 
> ...
> blah blah
> ..
> 
> i=55;
> whatever.num1=60

Richard Heathfield has already commented on the missing semicolon on
that line.

> memcpy(&mystr[4],&whatever,sizeof(struct MixedData));

I prefer mystr+4 over &mystr[4], just because it's simpler.
I prefer sizeof whatever over sizeof(struct MixedData), because it will
continue to calculate the correct quantity, even if you change the type
of whatever.

You're assuming mystr is at least 4 bytes bigger than whatever. That
assumption is probably correct, but I'd recommend either testing that
assumption:

    if(4+sizeof whatever > sizeof mystr)
    {
        // Error handling
    }

 or re-writing the code to guarantee that mystr is big enough:

    struct MixedData whatever;
    char mystr[4 + sizeof whatever];

By the way - what is the purpose of the "4"?

> ...
> blah blah
> ..
> memcpy(&whatever,&mystr[4],sizeof(struct MixedData));
> // i should be now 60

You last time a value was written to i, that value was 55. Why do you
think it would now be 60? For that matter, what is the purpose of i?


> Is above OK or should I worry about if my structed is padded or packed, ie. will
> sizeof() report correct value.

sizeof should always report the actual size, including padding bits or
bytes.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c


csiph-web