What is this?

Discussion in 'C Programming' started by Cesar Rodas, Jan 21, 2007.

  1. Cesar Rodas

    Cesar Rodas Guest

    Hello to all

    As far I know the unsigned char just use 1-byte, long 4-bytes... is
    this right???

    Well I have the next code...

    #include <stdio.h>
    #include <stdlib.h>

    typedef struct _foo
    {
    unsigned char lock;
    long a;
    long b;
    unsigned char data[1024];
    } bar;

    int main(int argc, char *argv[])
    {
    printf("%d\n", sizeof(bar));
    }

    /*******************************************************************************/
    WHY THE OUTPUT IS 1034? Is need to be 1024 + 4 + 4 + 1 = 1033

    Is something wrong?
    Cesar Rodas, Jan 21, 2007
    #1
    1. Advertising

  2. Cesar Rodas

    Chris Hills Guest

    In article <>, Cesar
    Rodas <> writes
    >Hello to all
    >
    >As far I know the unsigned char just use 1-byte, long 4-bytes... is
    >this right???


    No. It depends on your platform...

    Under ISO C there are certain minimum's but They could be larger.
    However many implementations, due to the hardware use non standard type
    sizes.


    >
    >Well I have the next code...
    >
    >#include <stdio.h>
    >#include <stdlib.h>
    >
    >typedef struct _foo
    >{
    >unsigned char lock;
    >long a;
    >long b;
    >unsigned char data[1024];
    >} bar;
    >
    >int main(int argc, char *argv[])
    >{
    >printf("%d\n", sizeof(bar));
    >}
    >
    >/***********************************************************************
    >********/
    >WHY THE OUTPUT IS 1034? Is need to be 1024 + 4 + 4 + 1 = 1033
    >
    >Is something wrong?
    >


    --
    \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
    \/\/\/\/\ Chris Hills Staffs England /\/\/\/\/
    /\/\/ www.phaedsys.org \/\/\
    \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
    Chris Hills, Jan 21, 2007
    #2
    1. Advertising

  3. Cesar Rodas

    matevzb Guest

    On Jan 21, 4:49 pm, "Cesar Rodas" <> wrote:
    > Hello to all
    >
    > As far I know the unsigned char just use 1-byte, long 4-bytes... is
    > this right???

    A char is always 1 byte, but a long may or may not be 4 bytes in size.
    > Well I have the next code...
    >
    > #include <stdio.h>
    > #include <stdlib.h>
    >
    > typedef struct _foo
    > {
    > unsigned char lock;
    > long a;
    > long b;
    > unsigned char data[1024];
    >
    > } bar;int main(int argc, char *argv[])
    > {
    > printf("%d\n", sizeof(bar));
    >
    > }/*******************************************************************************/
    > WHY THE OUTPUT IS 1034? Is need to be 1024 + 4 + 4 + 1 = 1033
    >
    > Is something wrong?

    No, nothing is wrong. This is called padding and the compiler does it
    to align the structure members according to their types. See the c.l.c
    FAQ (http://www.c-faq.com/struct/padding.html) for more detail.
    --
    WYCIWYG - what you C is what you get
    matevzb, Jan 21, 2007
    #3
  4. Cesar Rodas

    jacob navia Guest

    Cesar Rodas a écrit :
    > Hello to all
    >
    > As far I know the unsigned char just use 1-byte, long 4-bytes... is
    > this right???
    >
    > Well I have the next code...
    >
    > #include <stdio.h>
    > #include <stdlib.h>
    >
    > typedef struct _foo
    > {
    > unsigned char lock;
    > long a;
    > long b;
    > unsigned char data[1024];
    > } bar;
    >
    > int main(int argc, char *argv[])
    > {
    > printf("%d\n", sizeof(bar));
    > }
    >
    > /*******************************************************************************/
    > WHY THE OUTPUT IS 1034? Is need to be 1024 + 4 + 4 + 1 = 1033
    >
    > Is something wrong?
    >


    No
    Let us count:

    unsigned char lock; 1 byte
    long a; 4 bytes. BUT

    The long is aligned to an address multiple of four.
    This means that 3 bytes are left empty between the char
    and the long. This is why your structure is 3 bytes
    bigger than what you think
    jacob navia, Jan 21, 2007
    #4
  5. In article <>,
    "Cesar Rodas" <> wrote:


    > As far I know the unsigned char just use 1-byte, long 4-bytes...
    > is this right???


    This is right in many, but no all C implementations.
    The C standard implies that
    unsigned char can hold at least 8 bits
    unsigned long can hold at least 32 bits
    long can hold any value in the range -2147483647 to 2147483647

    > Well I have the next code...
    >
    > #include <stdio.h>
    > #include <stdlib.h>
    >
    > typedef struct _foo


    identifiers starting with _ are reserved; dont use them.

    > {
    > unsigned char lock;
    > long a;
    > long b;
    > unsigned char data[1024];
    > } bar;
    >
    > int main(int argc, char *argv[])
    > {
    > printf("%d\n", sizeof(bar));


    There is a potential bug here: sizeof(bar) is of type size_t, not int.
    Thus what is printed is undefined, from this group's standpoint.
    This is likely NOT bitting you right now, thought.

    > }


    likely, your compiler issues a warning for the lack of a return value.


    > WHY THE OUTPUT IS 1034?


    Likely, because the compiler decided to align the field a to some mutlple
    of 4 bytes, creating a hole of 3 bytes between lock and a.
    The compiler is free to do such things, and does. On many architectures
    (with a bus wider than 8-bit) this improve performance. On some
    architectures it may be necessary for the program to work at all.

    > Is need to be 1024 + 4 + 4 + 1 = 1033


    No it does not. The standard requires the result to be at least 1027
    (that could occur if sizeof(long) is 1). I'm unsure of a maximum.

    On architectures where alignment it is not absolutely necessary, the
    compiler often has a pragma to force the behaviour that you are expecting.


    Francois Grieu
    Francois Grieu, Jan 21, 2007
    #5
  6. "Cesar Rodas" <> writes:
    > As far I know the unsigned char just use 1-byte, long 4-bytes... is
    > this right???


    unsigned char is 1 byte by definition. The size of long can vary
    from one implementation to another.

    > Well I have the next code...
    >
    > #include <stdio.h>
    > #include <stdlib.h>
    >
    > typedef struct _foo
    > {
    > unsigned char lock;
    > long a;
    > long b;
    > unsigned char data[1024];
    > } bar;
    >
    > int main(int argc, char *argv[])
    > {
    > printf("%d\n", sizeof(bar));
    > }
    >
    > /*******************************************************************************/
    > WHY THE OUTPUT IS 1034? Is need to be 1024 + 4 + 4 + 1 = 1033
    >
    > Is something wrong?


    No, nothing is wrong.

    The comp.lang.c FAQ is at <http://www.c-faq.com/>. You've asked
    question 2.12 and/or 2.13.

    --
    Keith Thompson (The_Other_Keith) <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.
    Keith Thompson, Jan 21, 2007
    #6
  7. "Cesar Rodas" <> wrote in message
    news:...
    > Hello to all
    >
    > As far I know the unsigned char just use 1-byte, long 4-bytes... is
    > this right???
    >
    > Well I have the next code...
    >
    > #include <stdio.h>
    > #include <stdlib.h>
    >
    > typedef struct _foo
    > {
    > unsigned char lock;
    > long a;
    > long b;
    > unsigned char data[1024];
    > } bar;
    >
    > int main(int argc, char *argv[])
    > {
    > printf("%d\n", sizeof(bar));
    > }
    >
    > /*******************************************************************************/
    > WHY THE OUTPUT IS 1034? Is need to be 1024 + 4 + 4 + 1 = 1033
    >
    > Is something wrong?


    This question is covered here.

    http://www.c-faq.com/struct/padding.html

    There is a lot of modulo arithmetic involved, but the compiler HAS TO pad if
    there are alignment requirements for individual structure members.

    The general nature of the language requires that one be able to array
    structures using sizeof(struct) as the offset between them. This leads to
    some unexpected behavior.

    For example, assume that sizeof(long) is 4 with required mod 4 alignment,
    sizeof(int) is 2 with required mod 2 alignment, and sizeof(char) is 1 with
    required byte alignment.

    Consider these two structures:

    struct A {
    int x1;
    int x2;
    char c;
    }

    and

    struct B {
    long x;
    char c;
    }

    It might seem that the size of both structures is going to be equivalent,
    because they each sum to 5 bytes. Seem reasonable?

    Probably wrong. "B" needs to have a size of 8, because if the structure is
    arrayed, mod 4 alignment has to be achieved on every array element.
    However, "A" only needs to a size of 6, because only mod 2 alignment needs
    to be achieved on every element.

    Trying to guess what the compiler is going to do is a sure way to write
    platform-dependent code. sizeof() returns what it does. Don't even worry
    about what it will be or why.

    --
    David T. Ashley ()
    http://www.e3ft.com (Consulting Home Page)
    http://www.dtashley.com (Personal Home Page)
    http://gpl.e3ft.com (GPL Publications and Projects)
    David T. Ashley, Jan 21, 2007
    #7
  8. "Cesar Rodas" <> writes:
    [snip]
    > typedef struct _foo
    > {
    > unsigned char lock;
    > long a;
    > long b;
    > unsigned char data[1024];
    > } bar;

    [snip]
    > printf("%d\n", sizeof(bar));

    [snip]
    > WHY THE OUTPUT IS 1034? Is need to be 1024 + 4 + 4 + 1 = 1033


    Another question for you: *why* do you need sizeof bar to be 1033.

    It's likely that the answer is that you don't; the compiler knows what
    it needs to do, and you should stand back and let it do its job. But
    sometimes you do need to match some externally imposed data layout.
    If you can give us more details about what you're trying to do, we can
    probably help.

    --
    Keith Thompson (The_Other_Keith) <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.
    Keith Thompson, Jan 21, 2007
    #8
  9. On 21 Jan 2007 07:49:44 -0800, in comp.lang.c , "Cesar Rodas"
    <> wrote:

    (question about why the size of a struct was not the sum of the size
    of its members.)

    This is a FAQ.
    --
    Mark McIntyre

    "Debugging is twice as hard as writing the code in the first place.
    Therefore, if you write the code as cleverly as possible, you are,
    by definition, not smart enough to debug it."
    --Brian Kernighan
    Mark McIntyre, Jan 21, 2007
    #9
  10. Keith Thompson wrote:
    > "Cesar Rodas" <> writes:
    > > As far I know the unsigned char just use 1-byte, long 4-bytes... is
    > > this right???

    >
    > unsigned char is 1 byte by definition. The size of long can vary
    > from one implementation to another.


    It should be clarified here that in the C standard "byte"
    is a synonym for char and doesn't have to be exactly
    8 bits , simply at least 8 bits.
    Spiros Bousbouras, Jan 21, 2007
    #10
  11. Francois Grieu wrote:

    > There is a potential bug here: sizeof(bar) is of type size_t, not int.
    > Thus what is printed is undefined, from this group's standpoint.
    > This is likely NOT bitting you right now, thought.


    On the other hand, it will byte you really, really, really hard once
    you use a 64 bit compiler.

    Use the "zu" format specifier in C99, or cast to unsigned long and use
    "lu", which is safe for objects up to 4 GB.
    christian.bau, Jan 22, 2007
    #11
  12. Cesar Rodas

    iu2 Guest

    I work with a DSP which can only access 4-bytes memory addresses. Hence
    everything is 4-bytes: chars, ints, longs, floats... :eek:)
    iu2, Jan 22, 2007
    #12
  13. Cesar Rodas

    CBFalconer Guest

    iu2 wrote:
    >
    > I work with a DSP which can only access 4-bytes memory addresses.
    > Hence everything is 4-bytes: chars, ints, longs, floats... :eek:)


    So? You seem to have no problems or questions. See my sig. below.

    --
    If you want to post a followup via groups.google.com, ensure
    you quote enough for the article to make sense. Google is only
    a poor interface to usenet. There is no reason to assume your
    readers can, or ever will, see any previous articles.
    More details at: <http://cfaj.freeshell.org/google/>
    Also see <http://www.safalra.com/special/googlegroupsreply/>
    CBFalconer, Jan 22, 2007
    #13
  14. iu2 said:

    >
    > I work with a DSP which can only access 4-bytes memory addresses. Hence
    > everything is 4-bytes: chars, ints, longs, floats... :eek:)


    If sizeof(char) yields a result > 1, you're not using a conforming C
    implementation.

    char is always exactly one byte wide. Bytes may, however, contain any number
    of bits >= 8. The number of bits in a byte as far as your implementation is
    concerned is recorded by CHAR_BIT in <limits.h>

    Incidentally, like anything in standard headers, that's a read-only value;
    changing it is of no more value to you than scribbling over the "amount
    owing" part of the phone bill that drops through your door.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at the above domain, - www.
    Richard Heathfield, Jan 22, 2007
    #14
  15. Cesar Rodas

    Mike Wahler Guest

    "iu2" <> wrote in message
    news:...
    >
    > I work with a DSP which can only access 4-bytes memory addresses. Hence
    > everything is 4-bytes: chars, ints, longs, floats... :eek:)


    If your C implementation reports sizeof(char)
    as any value other than one, its 'CHAR_BIT'
    macro evaluates to less than eight, it's
    nonconforming.

    -Mike
    Mike Wahler, Jan 22, 2007
    #15
  16. Cesar Rodas

    Chris Dollin Guest

    Cesar Rodas wrote:

    > As far I know the unsigned char just use 1-byte, long 4-bytes... is
    > this right???


    No.

    > #include <stdio.h>
    > #include <stdlib.h>
    >
    > typedef struct _foo
    > {
    > unsigned char lock;
    > long a;
    > long b;
    > unsigned char data[1024];
    > } bar;
    >
    > int main(int argc, char *argv[])
    > {
    > printf("%d\n", sizeof(bar));
    > }
    >
    > /*******************************************************************************/
    > WHY THE OUTPUT IS 1034? Is need to be 1024 + 4 + 4 + 1 = 1033
    >
    > Is something wrong?


    Yes.

    [sizeof struct uselessunderbarwhydidyoubotherfoo is
    sizeof char (ie 1) + compiler-whim padding
    + sizeof long + compiler-whim padding
    + sizeof long + compiler-whim padding
    + sizeof char[1024] (ie 1024) + compiler-whim padding]

    --
    Chris "yes/no questions are just what I need right now" Dollin
    "Our future looks secure, but it's all out of our hands"
    - Magenta, /Man and Machine/
    Chris Dollin, Jan 22, 2007
    #16
  17. "iu2" <> writes:
    > I work with a DSP which can only access 4-bytes memory addresses. Hence
    > everything is 4-bytes: chars, ints, longs, floats... :eek:)


    Please provide context when you post a followup. Don't assume that
    your readers can easily see the article to which you're replying. See
    <http://cfaj.freeshell.org/google/>.

    In C, a char is one byte by definition. A "byte" in C is at least 8
    bits, but it can be larger.

    --
    Keith Thompson (The_Other_Keith) <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.
    Keith Thompson, Jan 22, 2007
    #17
  18. Cesar Rodas

    Cesar Rodas Guest

    Keith Thompson wrote:
    > "Cesar Rodas" <> writes:
    > [snip]
    > > typedef struct _foo
    > > {
    > > unsigned char lock;
    > > long a;
    > > long b;
    > > unsigned char data[1024];
    > > } bar;

    > [snip]
    > > printf("%d\n", sizeof(bar));

    > [snip]
    > > WHY THE OUTPUT IS 1034? Is need to be 1024 + 4 + 4 + 1 = 1033

    >
    > Another question for you: *why* do you need sizeof bar to be 1033.

    I need because I want to write a file that need to be read in windows,
    linux, freebsd and mobile handlers.
    >
    > It's likely that the answer is that you don't; the compiler knows what
    > it needs to do, and you should stand back and let it do its job. But
    > sometimes you do need to match some externally imposed data layout.
    > If you can give us more details about what you're trying to do, we can
    > probably help.
    >
    > --
    > Keith Thompson (The_Other_Keith) <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.
    Cesar Rodas, Jan 22, 2007
    #18
  19. Cesar Rodas

    Chris Dollin Guest

    Cesar Rodas wrote:

    >
    > Keith Thompson wrote:
    >> "Cesar Rodas" <> writes:
    >> [snip]
    >> > typedef struct _foo
    >> > {
    >> > unsigned char lock;
    >> > long a;
    >> > long b;
    >> > unsigned char data[1024];
    >> > } bar;

    >> [snip]
    >> > printf("%d\n", sizeof(bar));

    >> [snip]
    >> > WHY THE OUTPUT IS 1034? Is need to be 1024 + 4 + 4 + 1 = 1033

    >>
    >> Another question for you: *why* do you need sizeof bar to be 1033.

    > I need because I want to write a file that need to be read in windows,
    > linux, freebsd and mobile handlers.


    You don't need sizeof(bar) to be 1033 to do that.

    You're trying the tempting shortcut of

    int written = fwrite( &bar, sizeof bar, 1, streamyThing );

    I suspect. Fall not into temptation, for it will turn round and
    bite your arteries when you're not looking.

    --
    Chris "electric hedgehog" Dollin
    "People are part of the design. It's dangerous to forget that." /Star Cops/
    Chris Dollin, Jan 22, 2007
    #19
  20. In article <>,
    Cesar Rodas <> wrote:

    >> > WHY THE OUTPUT IS 1034? Is need to be 1024 + 4 + 4 + 1 = 1033


    >> Another question for you: *why* do you need sizeof bar to be 1033.


    >I need because I want to write a file that need to be read in windows,
    >linux, freebsd and mobile handlers.


    Writing structures directly is not portable. Not only may the total
    size be different, but the representation of the parts may be
    different too. For example, the byte order may be different.

    Do it some other way, for example by writing functions to write each
    part of the structure.

    -- Richard

    --
    "Consideration shall be given to the need for as many as 32 characters
    in some alphabets" - X3.4, 1963.
    Richard Tobin, Jan 22, 2007
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page