sizeof unpadded struct size

S

sinbad

how to make sizeof return unpadded struct size;

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

sizeof(struct abc) returns 12 padding 3 bytes for x;

But i need a way to determine the real unpadded size of struct abc
which is 9;

one way is to compute it statically, it there any other way for this?


thanks
 
I

Ian Collins

sinbad said:
how to make sizeof return unpadded struct size;

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

sizeof(struct abc) returns 12 padding 3 bytes for x;

But i need a way to determine the real unpadded size of struct abc
which is 9;
12 is the real size, there isn't an "unpadded size". Your compiler
might have an option to pack structures.
 
M

Martin Ambuhl

sinbad said:
how to make sizeof return unpadded struct size;

"Unpadded struct size" is a meaningless phrase, since the size of the
struct is an unqualified concept. However, I think I know what you mean.
See blow.
struct abc {
int z;
int y;
char x;
};

sizeof(struct abc) returns 12 padding 3 bytes for x;

sizeof(struct abc) returns the size of the struct. Period.
But i need a way to determine the real unpadded size of struct abc
which is 9;

And "real unpadded size" is meaningless. The real size of the struct is
the value returned by sizeof. Its reality as the struct size is
unqualified.
one way is to compute it statically, it there any other way for this?

It seems clear that you have no interest in the size of struct abc.
It seems that what you want is something completely differemt, the sum
of the sizes of the named and visible members of that struct. The answer
is clear: add together the sizes of the members of the struct:

#include <stdio.h>

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

int main(void)
{
struct abc foo;
printf("On this implementation, a struct abc takes %zu bytes.\n\n",
sizeof(struct abc));
printf("Here is a poor way to determine the size of the members\n"
"Using a null pointer to a non-existent instance of"
" the struct.\n"
"The member z takes %zu bytes.\n"
"The member y takes %zu bytes.\n"
"The member x takes %zu bytes.\n"
"The sum of these is %zu bytes.\n\n",
sizeof(((struct abc *) 0)->z),
sizeof(((struct abc *) 0)->y),
sizeof(((struct abc *) 0)->x),
sizeof(((struct abc *) 0)->z) +
sizeof(((struct abc *) 0)->y) +
sizeof(((struct abc *) 0)->x));
printf("The better way is to use an actual instance.\n"
"The member z takes %zu bytes.\n"
"The member y takes %zu bytes.\n"
"The member x takes %zu bytes.\n"
"The sum of these is %zu bytes.\n\n",
sizeof foo.z,
sizeof foo.y,
sizeof foo.x,
sizeof foo.z +
sizeof foo.y +
sizeof foo.x);
return 0;
}


On this implementation, a struct abc takes 12 bytes.

Here is a poor way to determine the size of the members
Using a null pointer to a non-existent instance of the struct.
The member z takes 4 bytes.
The member y takes 4 bytes.
The member x takes 1 bytes.
The sum of these is 9 bytes.

The better way is to use an actual instance.
The member z takes 4 bytes.
The member y takes 4 bytes.
The member x takes 1 bytes.
The sum of these is 9 bytes.
 
J

James Kuyper

sinbad said:
how to make sizeof return unpadded struct size;

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

sizeof(struct abc) returns 12 padding 3 bytes for x;

But i need a way to determine the real unpadded size of struct abc
which is 9;

"real" and "unpadded" are contradictory in this context. The "real" size
includes the padding, since the padding is "really" present. What you
want to calculate is the unreal unpadded size. The C language doesn't
help you with that. However, many compilers provide some way of ensuring
that the struct is not padded; a #pragma named 'pack' or 'packed' is
popular, though it has different syntax on different systems. If you use
that option, then the real size and the unpadded size will be the same
thing, and sizeof will give you that size.
 
C

Chris Dollin

sinbad said:
how to make sizeof return unpadded struct size;

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

sizeof(struct abc) returns 12 padding 3 bytes for x;

But i need a way to determine the real unpadded size of struct abc
which is 9;

Why?
 
T

Tomás Ó hÉilidhe

how to make sizeof return unpadded struct size;

struct abc {
int z;
int y;
char x;

};

sizeof(struct abc) returns 12 padding 3 bytes for x;

But i need a way to determine the real unpadded size of struct abc
which is 9;

one way is to compute it statically, it there any other way for this?



The Standard C language has no convenient facility for doing this, you
have to spell out all the members:

sizeof obj.z + sizeof obj.y + sizeof obj.x

A non-standard C method would be to use a compiler extension that
ensures a lack of padding, and then just use "sizeof" on the unpadded
struct.
 
P

Phil Carmody

Ian Collins said:
12 is the real size, there isn't an "unpadded size". Your compiler
might have an option to pack structures.

Not knowing exactly why he wants what he wants, it's hard to know if
there's really no way to know if what he wants to achieve is possible,
or even if it is sensible.

However, simply on face value, the offsetof the last member plus
the sizeof the last member would give a numerically equivalent value
to what he claims to want. That value, however, I cannot imagine
having much sensible real-world use. Re-order the members, and you
might get a different value for the 'size', so it's not really a
measure of the contents of the structure (which the sum of the
sizeof's of the individual members would be).

Phil
 
E

Eric Sosman

sinbad said:
how to make sizeof return unpadded struct size;

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

sizeof(struct abc) returns 12 padding 3 bytes for x;

But i need a way to determine the real unpadded size of struct abc
which is 9;

sizeof(struct abc) *is* the number of bytes in an instance
of the struct. There is no such thing as "the real unpadded
size." 2*sizeof(int)+sizeof(char) is a number, yes, but a
number that has nothing much to do with the size of the struct.
You can deduce that the size of the struct is at least as great
as the sum, but that's all.

Here's an analogy, inaccurate as analogies always are but
perhaps it will help you understand: What is your weight, not
counting your water content? You could add up the weight of
the collagen and cartilage, the bones and bursae, and all the
other non-watery bits and pieces of yourself, and announce a
number. But would that number have anything to do with "your"
weight? The water is an essential part of "you," just as the
padding is an essential part of the struct: Neither you nor
the struct can exist without your essential ingredients, and
a measurement that ignores essential ingredients is not very
meaningful.
 
J

James Kuyper

Phil said:
Not knowing exactly why he wants what he wants, it's hard to know if
there's really no way to know if what he wants to achieve is possible,
or even if it is sensible.

However, simply on face value, the offsetof the last member plus
the sizeof the last member would give a numerically equivalent value
to what he claims to want.

Only if there's no internal padding. That's certainly unlikely in this
case, but not in general, and even in this case it would be permitted.
 
D

Dik T. Winter

> However, simply on face value, the offsetof the last member plus
> the sizeof the last member would give a numerically equivalent value
> to what he claims to want.

No, padding does not only occur at the end of a struct.
 
B

Bartc

Chris Dollin said:

To find out the true size of the struct. The padding at the end is there so
you can have more than one consecutively in memory without alignment
problems.

If there is only one struct, this is unnecessary.

Turning off padding is not always a solution (nor is summing the sizes of
the elements), since the padding /between/ elements may be necessary.
 
P

Phil Carmody

James Kuyper said:
Only if there's no internal padding. That's certainly unlikely in this
case, but not in general, and even in this case it would be permitted.

s/un//;

The nonsense "real" in his question implies that he doesn't know that
he actually wants. And as I said above, without knowing exactly what
the real problem is, it's hard to know what, if any, the best solution
to his problem might be. Is he just after a minimal size to memcpy?
6.2.6.1 seems to imply that trailing padding does not need to be
copied in such cases (or internal padding, but you can't get memcpy
to skip bytes, whereas you can get it to not copy unnecessary terminal
bytes).

And as I said later, but you snipped, if all he wants is the sum
of the sizes of the members of the struct, all he needs to do is
sum the sizes of the members of the struct.

Phil
 
B

Bartc

Eric Sosman said:
The "as if rule" grants wide latitude, but it's hard to imagine
how different sizes for different instances of a struct could be
made to work. For example (headers and error-checking omitted):

I wasn't suggesting a struct could have more than one sizeof value. Only
that the size of the struct, less the end-padding, is meaningful and could
be useful. In a contrived example:

struct s{double x; char a;};

is reported to be of size 16 bytes on my machine, but I know that this
includes 7 bytes of end-padding.

If I'm reading a file consisting of a series of (double, char) values, and I
want to read that into a memory array of such structs, then I'd rather read
9 bytes at a time instead of 16.

(However a more typical problem is that in-between padding needed for
alignment is not present in a file, which might need reading in even smaller
chunks.)
 
C

CBFalconer

Bartc said:
.... snip ...

struct s{double x; char a;};

is reported to be of size 16 bytes on my machine, but I know that
this includes 7 bytes of end-padding.

If I'm reading a file consisting of a series of (double, char)
values, and I want to read that into a memory array of such
structs, then I'd rather read 9 bytes at a time instead of 16.

Not necessarily. The reading mechanism may be reading 64 bits at a
time, so two read cycles are needed for all 16 bytes. If you only
read 9 bytes it may require 9 relatively long reads, with shifts,
masks, etc.
 
P

Phil Carmody

Dik T. Winter said:
No, padding does not only occur at the end of a struct.

I presumed, that as he didn't just sum of the sizes of the
individual members that he was considering the internal
padding to be different from the final padding, and he
wanted what the mathematically inclined might call the
diameter. But you knew that already.

Phil
 
J

James Kuyper

Phil said:
Agreed.

The nonsense "real" in his question implies that he doesn't know that
he actually wants. And as I said above, without knowing exactly what
the real problem is, it's hard to know what, if any, the best solution
to his problem might be. Is he just after a minimal size to memcpy?
6.2.6.1 seems to imply that trailing padding does not need to be
copied in such cases (or internal padding, but you can't get memcpy
to skip bytes, whereas you can get it to not copy unnecessary terminal
bytes).

And as I said later, but you snipped, if all he wants is the sum
of the sizes of the members of the struct, all he needs to do is
sum the sizes of the members of the struct.

I assumed that he wanted a simple way to get that same number without
explicitly performing the sum. I can't see any reason to make any more
complicated assumption, unless and until he says something more specific
about what he wants.
 
P

Peter Nilsson

sinbad said:
how to make sizeof return unpadded struct size;

struct abc {
int z;
int y;
char x;

};

sizeof(struct abc) returns 12 padding 3 bytes for x;

But i need a way to determine the real unpadded size
of struct abc which is 9;

one way is to compute it statically, it there any other
way for this?

You can calculate the sum of individual element sizes if
you're prepared to make your struct definitions a little
more elaborate. Below is a cut down version of a more
general technique that I use.

#include <stdio.h>

/* your struct abc members */
#define pp_struct_abc(M, _) \
M( int, z ) _ \
M( int, y ) _ \
M( char, x )

/* some utilities */
#define pp_as_struct(type_pp, name_pp) \
type_pp name_pp

#define pp_as_type_size(type_pp, name_pp) \
sizeof(type_pp)

/* defining the actual struct */
struct abc
{
pp_struct_abc(pp_as_struct, ; );
};

int main(void)
{
int padded = sizeof (struct abc);
int unpadded = pp_struct_abc(pp_as_type_size, +);

printf(" padded: %d bytes\n", padded);
printf("unpadded: %d bytes\n", unpadded);
printf(" padding: %d bytes\n", padded - unpadded);

return 0;
}
 
C

Chris Dollin

Bartc said:
To find out the true size of the struct. The padding at the end is there so
you can have more than one consecutively in memory without alignment
problems.

With respect, Bartc, I want sinbad's answer, not yours.

You make the same assumption they do: that there is a "true size"
different from the /actual/ size, viz, the size that sizeof says.
Whether the number 9 means anything /useful/ with respect to the
size of struct abc we don't know.
If there is only one struct, this is unnecessary.

I would not be so sure. If there is only one struct /whose address is
not taken/, that I might grant. In that case, the compiler can likely
as-if the extra bytes away.
Turning off padding is not always a solution (nor is summing the sizes of
the elements), since the padding /between/ elements may be necessary.

The other aspect of my "why" is "if you knew the answer, what would you
do with it?". At this stage, only sinbad knows.
 
B

Bartc

With respect, Bartc, I want sinbad's answer, not yours.

OK, but you might have to wait a while. OPs frequently ask a question then
are never heard of again when asked for clarification.
Whether the number 9 means anything /useful/ with respect to the
size of struct abc we don't know.

Well, for a start, it means we're wasting 3 bytes that might as well be used
to store extra data. Although this is of more use at programming time than
runtime.
The other aspect of my "why" is "if you knew the answer, what would you
do with it?". At this stage, only sinbad knows.

Yes, it's a mystery.
 
P

Phil Carmody

pete said:
You are correct and Phil Carmody is just simply wrong.

You again appear to not understand that Dik and I are answering
different questions. Try comprehending after reading, and things
might make more sense.

Phil
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top