union size

A

asit

#include <stdio.h>
//#include <strlen.h>
union xxx
{
char name[10];
double d;
int ff;
};

int main()
{
union xxx s;
printf("%d\n",sizeof(s));
getch();
return 0;
}

why o/p is 16 in GCC compiler ??
 
U

Ulrich Eckhardt

asit said:
#include <stdio.h>
union xxx
{
char name[10];
double d;
int ff;
};

int main()
{
union xxx s;
printf("%d\n",sizeof(s));
getch();
return 0;
}

why o/p is 16 in GCC compiler ??

The thing is called 'padding' and necessary due to 'alignment constraints'
on your platform. Those two terms and a websearch should yield lots of
explanations. ;)

Uli
 
J

James Kuyper

asit wrote:
....
printf("%d\n",sizeof(s));

The "%d" format code requires that the corresponding argument have a
promoted type of 'int'. sizeof() returns a value of type size_t, which
may or may not be unsigned int, but is guaranteed to be an unsigned type
of some kind. It has a pretty good chance of being a type larger than 'int'.

In C89, you should use

printf("%lu\n", (unsigned long)sizeof(s));

In C99, it's simpler:

printf("%zu\n", sizeof(s));
 
C

Chris Dollin

asit said:
#include <stdio.h>
//#include <strlen.h>
union xxx
{
char name[10];
double d;
int ff;
};

int main()
{
union xxx s;
printf("%d\n",sizeof(s));
getch();
return 0;
}

why o/p is 16 in GCC compiler ??

Assuming for the moment that printing a `size_t` through an
`int`-printing format doesn't shift you into an alternate
reality [1], it's because a `union xxx` object has size 16.

It's got to have size at least 10, because of the `name`
field. And it's got to be an integer multiple of the size
of `double` and `int` if your implementation needs to
align those types properly for efficiency. Let's suppose
we can ignore the `int` in favour of the `double` for now.

If double's size were 2, 5, or 10 there'd not need to be
extra padding to get the alignment right. If it were 3 or 4
or 6, we'd only need to pad to 12 bytes; if it were 7,
we'd only need to pad to 14 bytes.

8, however, requires padding to 16 bytes. I expect that
sizeof double = 16 on your implementation and that's your
seeing the padding requirement.

[1] Watch out for Cybermen, earpods, and nine-bit bytes.
 
H

Harald van Dijk

asit said:
union xxx
{
char name[10];
double d;
int ff;
};

It's got to have size at least 10, because of the `name` field. And it's
got to be an integer multiple of the size of `double` and `int` if your
implementation needs to align those types properly for efficiency.

A double could have a size of 8, but require alignment on 4-byte
boundaries. Assuming the requirements for int don't get in the way, this
allows sizeof(union xxx) to be 12, which is a multiple of 4, but not a
multiple of 8. (This is what happens on the implementation I'm using.)
 
K

Keith Thompson

asit said:
#include <stdio.h>
//#include <strlen.h>

No such header; good thing it's commented out.
union xxx
{
char name[10];
double d;
int ff;
};

int main()
{
union xxx s;
printf("%d\n",sizeof(s));

Others have commented on the correct way to print a size_t value.

No such standard function.
return 0;
}

why o/p is 16 in GCC compiler ??

The output will vary, even for gcc, across different platforms. I get
16 with gcc under SPARC/Solaris, 12 with gcc under x64/Linux.

The size of types double and int can vary across different systems.
It's even possible that sizeof(double)==16, which would neatly explain
why sizeof(struct xxx)==16.

It's more likely (given what I know of gcc) that sizeof(double)==8 and
sizeof(int)==4; you should verify this for your system. If so, then
the compiler has inserted extra padding. It didn't *have* to do this,
but it was probably more convenient for some reason. Compilers are
allowed to insert arbitary padding between struct members and/or at
the end of a struct or union; they don't even have to have a good
reason for doing so.

If you're interested in the gcc-specific details, try asking in
gnu.gcc.help.
 
C

Chris Dollin

Harald said:
asit said:
union xxx
{
char name[10];
double d;
int ff;
};

It's got to have size at least 10, because of the `name` field. And it's
got to be an integer multiple of the size of `double` and `int` if your
implementation needs to align those types properly for efficiency.

A double could have a size of 8, but require alignment on 4-byte
boundaries.

You're quite right; thanks for spotting that.
Assuming the requirements for int don't get in the way, this
allows sizeof(union xxx) to be 12, which is a multiple of 4, but not a
multiple of 8. (This is what happens on the implementation I'm using.)

And we can conclude that you're using a different implementation
from the OP -- a splendid example of subtle differences.
 
S

Serve Lau

James Kuyper said:
asit wrote:
...

The "%d" format code requires that the corresponding argument have a
promoted type of 'int'. sizeof() returns a value of type size_t, which may
or may not be unsigned int, but is guaranteed to be an unsigned type of
some kind. It has a pretty good chance of being a type larger than 'int'.

In C89, you should use

printf("%lu\n", (unsigned long)sizeof(s));

This is correct, but isnt it a bit overkill when you are 100% sure that
sizeof(s) will fit into an int
 
J

James Kuyper

Serve said:
"James Kuyper" <[email protected]> schreef in bericht


This is correct, but isnt it a bit overkill when you are 100% sure that
sizeof(s) will fit into an int

If you're absolutely certain of that (and for sizeof it's commonplace to
be sure), then

printf("%d\n", (int)sizeof(s));

would be fine. The important thing is to make sure the argument type
matches your format code.
 
V

Victor Blood

#include <stdio.h>
//#include <strlen.h>
union xxx
{
      char name[10];
      double d;
      int ff;

};

int main()
{
    union xxx s;
    printf("%d\n",sizeof(s));
    getch();
    return 0;

}

why o/p is 16 in GCC compiler ??

It's will be on any compiller that used intel standards, this aligment
of structure to PARA is nessasary to increase perfomance.

If you need no aligment (work with file record, or any one over
structure that no included in arrays), you may use #pragma
pack(<aligment size>)

#include <stdio.h>

// BYTE ALIGMENT
#pragma pack(1)
union xxx
{
char name[10];
double d;
int ff;

};

// PARA ALIGMENT
#pragma pack(16)

int main()
{
union xxx s;
printf("%d\n",sizeof(s));
getch();
return 0;

}

now it's prints 10

PS: sorry for my english
 
K

Keith Thompson

Victor Blood said:
#include <stdio.h>
//#include <strlen.h>
union xxx
{
      char name[10];
      double d;
      int ff;

};

int main()
{
    union xxx s;
    printf("%d\n",sizeof(s));
    getch();
    return 0;

}

why o/p is 16 in GCC compiler ??

It's will be on any compiller that used intel standards, this aligment
of structure to PARA is nessasary to increase perfomance.

Using gcc on a system with an Intel CPU, I get 12. Maybe the compiler
isn't following "Intel standards", whatever that means, but I think
you're over-generalizing.

And I have no idea what "PARA" means. (Paragraph, maybe?)
If you need no aligment (work with file record, or any one over
structure that no included in arrays), you may use #pragma
pack(<aligment size>)

Not in standard C. Some compilers may support "#pragma pack"; others
don't, or may support it with a different meaning. For example, I
think that "#pragma pack(N)" might specify either N-bit alignment or
2**N bit alignment, depending on the compiler.
 

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,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top