Thread: Question about sizeof()

  1. #1
    Registered User
    Join Date
    Dec 2005
    Posts
    167

    Question about sizeof()

    I want to implement a package header for a client using a structure.
    Code:
    typedef struct header
    {
            short ID;
            short opt;      //QR(1) Opcode(4) AA(1) TC(1) RD(1) RA(1) Z(3) RCODE(4)
            short QDCOUNT;
            short ANCOUNT;
            short NSCOUNT;
            short ARCOUNT;
    } header;
    it is posible that sizeof(short) to be different on various boxes? on mine is 2. The structure is always sum of sizes of the components inside the structure ?
    Sorry if this question seems dumb!

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Yes, sizeof(short) can vary from one machine to another.

    Also, the size of a whole struct can be larger than the sum of the sizes all its members.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Dec 2005
    Posts
    167
    why does this happen? why does the size of the struct is larger than is members?

  4. #4
    Registered User
    Join Date
    Dec 2005
    Posts
    167
    the problem is that i want to create a structure an to be sure of the size of the struct on all computers that it runs on. how can i assure that ?

  5. #5
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by spank View Post
    why does this happen? why does the size of the struct is larger than is members?
    The compiler is free to add padding between elements of the struct, or at the end of the struct, to comply with platform-specific alignment requirements. Therefore, reading and writing structs directly from files using sizeof() to figure out how many bytes to write is non-portable. The sizeof() the struct can and will be different on different platforms.

    When you read or write a struct, there are two major issues to consider. First is the issue of padding, which I just described. Second is multibyte data format, i.e. endianness.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    In order to preserve efficient alignment of each member of the structure, a compiler is free to add 'padding' bytes between members of the struct (this pushes the size up).

    There is no way to ensure that a struct has the same size on all machines.
    Even if it were possible, you would still have to contend with this - http://en.wikipedia.org/wiki/Endianness

    If you're looking to transfer data outside a program (to a file, to another machine, etc), then you have to reduce the data to a byte stream and document the order.

    So for example, ID is 16 bits, low byte first.
    where your program would then do
    msg[0] = mystruct.ID & 0xff;
    msg[1] = (mystruct.ID >> 8 ) & 0xff;
    and so on.

    Tedious to be sure, but it's the only way to guarantee it works everywhere.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Dec 2005
    Posts
    167
    one of my problems now is that I have some fields in packet i need to transfer. For example i have a 1 byte field divided in two... first 4 bits are something... the last are another thing. I want to put in the first let say 3 and in the last 10

    unsigned char c;
    c=0x3A;

    does this do the trick? it is ready to go to the network? how can ensure that endianness is not a problem?

    Thank you for your answers! Really helps me!

  8. #8
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by spank View Post
    does this do the trick? it is ready to go to the network? how can ensure that endianness is not a problem?
    Endianness affects multibyte quantites, not single bytes.

  9. #9
    Registered User
    Join Date
    Dec 2005
    Posts
    167
    Sorry... my mistake.

    Bear with me I have char[2] field and I need to initialize it with a value of short to pass it through the network. How can I do that?

    I want to make a dns client and I have to send a multibyte package (Header+Question) and I don't seem to send the right package to the server.
    Last edited by spank; 05-12-2007 at 01:06 AM. Reason: complet my post

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    I just showed you how to do that.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  11. #11
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    The third issue, not mentioned yet, is data representation. Your shorts are signed. C++ places only two requirements on the representation of signed numbers:
    1) If all value bits are zero, the value is zero.
    2) The common value subset of signed and unsigned integers (e.g. 0 through 2^15-1 for 16-bit integers) must have the same representation.

    In practice, this allows three distinct representations: 2's complement (most popular by far), 1's complement and sign-value.
    If you transfer negative values, you have to document which representation you use, too.


    Of course, the fields above don't look like they could ever be negative. Consider making them unsigned shorts.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  12. #12
    Registered User
    Join Date
    Dec 2005
    Posts
    167
    salem thank you for your answer... As i understand your suggestion is to switch the byte order (from what i get from that code). But what if my program uses the same endianness as the network. I don't have to switch it?

  13. #13
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > But what if my program uses the same endianness as the network.
    Programs don't use endian-ess, machines do.
    Recompile your code on another machine, and it might just stop working, unless you do this.

    FYI, you can use htons() and htonl() (and the corresponding reversal functions) to ease the task of turning your data into "network byte order" and back again.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Read from 15-pin port
    By C_ntua in forum C Programming
    Replies: 23
    Last Post: 07-11-2008, 09:09 AM
  2. sizeof union question
    By noops in forum C Programming
    Replies: 13
    Last Post: 06-06-2008, 11:56 AM
  3. Design layer question
    By mdoland in forum C# Programming
    Replies: 0
    Last Post: 10-19-2007, 04:22 AM
  4. Malloc,calloc..Sscanf.
    By ozumsafa in forum C Programming
    Replies: 22
    Last Post: 07-26-2007, 01:09 AM
  5. sizeof() EZ question
    By V1P3R V3N0M in forum Windows Programming
    Replies: 15
    Last Post: 01-11-2003, 11:25 PM