Why the sizeof is 4

Discussion in 'C Programming' started by Hill Pang, Jun 12, 2012.

  1. Hill Pang

    Hill Pang Guest

    The is my code:

    struct f1 {
    int x; int y[];
    } f1 = { 1, { 2, 3, 4 } };

    void main()
    {
    printf("sizeof %d\n", sizeof f1);
    }

    The output(by GCC) is 4.
    My question is why it doesn't count the size of the flexible array while it is static initialized?
    In other words, if I want to know the *really* size of f1, how to do it? is it possible?
     
    Hill Pang, Jun 12, 2012
    #1
    1. Advertising

  2. Hill Pang wrote:
    > The is my code:
    >
    > struct f1 {
    > int x; int y[];
    > } f1 = { 1, { 2, 3, 4 } };
    >
    > void main()
    > {
    > printf("sizeof %d\n", sizeof f1);
    > }
    >
    > The output(by GCC) is 4.
    > My question is why it doesn't count the size of the flexible array while it is static initialized?
    > In other words, if I want to know the *really* size of f1, how to do it? is it possible?


    Not using sizeof alone.
    You could try:

    struct f1 {
    int x; size_t size; int y[];
    } f1 = { 1, 3, { 2, 3, 4 } };

    void main()
    {
    printf("sizeof %d\n", sizeof(f1)+sizeof(f1.y)*f1.size);
    }

    possibly wrap it in some #define

    I doubt it is safe to use in a static declaration like this.
    You may be overrunning the end...
    Better do a malloc(), or declare with y[3].
     
    Johann Klammer, Jun 12, 2012
    #2
    1. Advertising

  3. Hill Pang

    Ian Collins Guest

    On 06/12/12 03:39 PM, Hill Pang wrote:
    > struct f1 {
    > int x; int y[];
    > } f1 = { 1, { 2, 3, 4 } };


    If your compiler didn't warn about this, turn the volume up until it does!

    > void main()


    Ditto this.

    --
    Ian Collins
     
    Ian Collins, Jun 12, 2012
    #3
  4. Hill Pang

    Ian Collins Guest

    On 06/12/12 03:39 PM, Hill Pang wrote:
    > The is my code:
    >
    > struct f1 {
    > int x; int y[];
    > } f1 = { 1, { 2, 3, 4 } };
    >
    > void main()
    > {
    > printf("sizeof %d\n", sizeof f1);
    > }
    >
    > The output(by GCC) is 4.
    > My question is why it doesn't count the size of the flexible array while it is static initialized?


    See paragraph 17 in section 6.7.2.1 of C99 and note the example.

    > In other words, if I want to know the *really* size of f1, how to do it? is it possible?


    No, you have to save it explicitly somewhere.

    --
    Ian Collins
     
    Ian Collins, Jun 12, 2012
    #4
  5. Hill Pang

    Ike Naar Guest

    On 2012-06-12, Johann Klammer <1.net> wrote:
    > printf("sizeof %d\n", sizeof(f1)+sizeof(f1.y)*f1.size);


    sizeof f1.y is wrong,
    you probably meant sizeof f1.y[0] or sizeof *f1.y .
     
    Ike Naar, Jun 12, 2012
    #5
  6. Hill Pang

    Zhang Yuan Guest

    On Tuesday, June 12, 2012 1:11:15 PM UTC+8, Johann Klammer wrote:
    > Hill Pang wrote:
    > > The is my code:
    > >
    > > struct f1 {
    > > int x; int y[];
    > > } f1 = { 1, { 2, 3, 4 } };
    > >
    > > void main()
    > > {
    > > printf("sizeof %d\n", sizeof f1);
    > > }
    > >
    > > The output(by GCC) is 4.
    > > My question is why it doesn't count the size of the flexible array while it is static initialized?
    > > In other words, if I want to know the *really* size of f1, how to do it? is it possible?

    >
    > Not using sizeof alone.
    > You could try:
    >
    > struct f1 {
    > int x; size_t size; int y[];
    > } f1 = { 1, 3, { 2, 3, 4 } };
    >
    > void main()
    > {
    > printf("sizeof %d\n", sizeof(f1)+sizeof(f1.y)*f1.size);

    why sizeof(f1) become to 8;?

    > }
    >
    > possibly wrap it in some #define
    >
    > I doubt it is safe to use in a static declaration like this.
    > You may be overrunning the end...
    > Better do a malloc(), or declare with y[3].
     
    Zhang Yuan, Jun 12, 2012
    #6
  7. Hill Pang

    Zhang Yuan Guest

    On Tuesday, June 12, 2012 1:11:15 PM UTC+8, Johann Klammer wrote:
    > Hill Pang wrote:
    > > The is my code:
    > >
    > > struct f1 {
    > > int x; int y[];
    > > } f1 = { 1, { 2, 3, 4 } };
    > >
    > > void main()
    > > {
    > > printf("sizeof %d\n", sizeof f1);
    > > }
    > >
    > > The output(by GCC) is 4.
    > > My question is why it doesn't count the size of the flexible array while it is static initialized?
    > > In other words, if I want to know the *really* size of f1, how to do it? is it possible?

    >
    > Not using sizeof alone.
    > You could try:
    >
    > struct f1 {
    > int x; size_t size; int y[];
    > } f1 = { 1, 3, { 2, 3, 4 } };
    >



    > void main()
    > {
    > printf("sizeof %d\n", sizeof(f1)+sizeof(f1.y)*f1.size);
    > }
    >
    > possibly wrap it in some #define
    >
    > I doubt it is safe to use in a static declaration like this.
    > You may be overrunning the end...
    > Better do a malloc(), or declare with y[3].




    On Tuesday, June 12, 2012 1:11:15 PM UTC+8, Johann Klammer wrote:
    > Hill Pang wrote:
    > > The is my code:
    > >
    > > struct f1 {
    > > int x; int y[];
    > > } f1 = { 1, { 2, 3, 4 } };
    > >
    > > void main()
    > > {
    > > printf("sizeof %d\n", sizeof f1);
    > > }
    > >
    > > The output(by GCC) is 4.
    > > My question is why it doesn't count the size of the flexible array while it is static initialized?
    > > In other words, if I want to know the *really* size of f1, how to do it? is it possible?

    >
    > Not using sizeof alone.
    > You could try:
    >
    > struct f1 {
    > int x; size_t size; int y[];
    > } f1 = { 1, 3, { 2, 3, 4 } };
    >
    > void main()
    > {
    > printf("sizeof %d\n", sizeof(f1)+sizeof(f1.y)*f1.size);
    > }

    why sizeof(f1) changed from 4 to 8 ?

    >
    > possibly wrap it in some #define
    >
    > I doubt it is safe to use in a static declaration like this.
    > You may be overrunning the end...
    > Better do a malloc(), or declare with y[3].
     
    Zhang Yuan, Jun 12, 2012
    #7
  8. Hill Pang

    James Kuyper Guest

    On 06/12/2012 07:02 AM, Zhang Yuan wrote:
    > On Tuesday, June 12, 2012 1:11:15 PM UTC+8, Johann Klammer wrote:

    ....
    >> struct f1 {
    >> int x; size_t size; int y[];
    >> } f1 = { 1, 3, { 2, 3, 4 } };
    >>
    >> void main()
    >> {
    > > printf("sizeof %d\n", sizeof(f1)+sizeof(f1.y)*f1.size);

    > why sizeof(f1) become to 8;?


    It now includes both 'x' and 'size'. It does not include y: "the size of
    the structure is as if the flexible array member were omitted except
    that it may have more trailing padding than the omission would imply."
    (6.7.2.1p18)

    --
    James Kuyper
     
    James Kuyper, Jun 12, 2012
    #8
  9. Zhang Yuan wrote:
    >> void main()
    > > {
    > > printf("sizeof %d\n", sizeof(f1)+sizeof(f1.y)*f1.size);

    Sorry, Imade a mistake. it should be: "sizeof(f1)+sizeof(f1.y[0])*f1.size"
    as Ike Naar posted earlier.
    > > }

    > why sizeof(f1) changed from 4 to 8 ?
    >


    It is now something like sizeof(int)+sizeof(size_t).
    But may be more if padding is inserted by compiler.
     
    Johann Klammer, Jun 12, 2012
    #9
  10. Hill Pang

    Hill Pang Guest

    On Tuesday, June 12, 2012 1:31:04 PM UTC+8, Ian Collins wrote:
    > On 06/12/12 03:39 PM, Hill Pang wrote:
    > > The is my code:
    > >
    > > struct f1 {
    > > int x; int y[];
    > > } f1 = { 1, { 2, 3, 4 } };
    > >
    > > void main()
    > > {
    > > printf("sizeof %d\n", sizeof f1);
    > > }
    > >
    > > The output(by GCC) is 4.
    > > My question is why it doesn't count the size of the flexible array while it is static initialized?

    >
    > See paragraph 17 in section 6.7.2.1 of C99 and note the example.
    >
    > > In other words, if I want to know the *really* size of f1, how to do it? is it possible?

    >
    > No, you have to save it explicitly somewhere.
    >
    > --


    Yes, C99 will ignore the flexible array member while counting the structuresize, but in C99 it also specify that the flexible array member could not be static initialized, the example shows it:
    >> struct s t2 = { 1, { 4.2 }}; // invalid.


    So the static initialization to flexible array member is a extension of GCC, while it is initialized statically, from my opinion, it should make senseto count the size of the flexible array member. I would suggest this as a enhancement of GCC to the great GCC developer.

    > Ian Collins
     
    Hill Pang, Jun 12, 2012
    #10
  11. Hill Pang wrote:
    >
    > Yes, C99 will ignore the flexible array member while counting the structure size, but in C99 it also specify that the flexible array member could not be static initialized, the example shows it:
    >>> struct s t2 = { 1, { 4.2 }}; // invalid.

    >
    > So the static initialization to flexible array member is a extension of GCC, while it is initialized statically, from my opinion, it should make sense to count the size of the flexible array member. I would suggest this as a enhancement of GCC to the great GCC developer.


    I doubt this is possible, as the sizeof is a property of the type, and
    you would want it different depending on initialisation.
    The fact that gcc compiles the code may be a bug. Are you sure, it
    actually reserves space for the supplied values?
     
    Johann Klammer, Jun 12, 2012
    #11
  12. Hill Pang

    Hill Pang Guest

    On Tuesday, June 12, 2012 10:07:22 PM UTC+8, Johann Klammer wrote:
    > Hill Pang wrote:
    > >
    > > Yes, C99 will ignore the flexible array member while counting the structure size, but in C99 it also specify that the flexible array member could not be static initialized, the example shows it:
    > >>> struct s t2 = { 1, { 4.2 }}; // invalid.

    > >
    > > So the static initialization to flexible array member is a extension ofGCC, while it is initialized statically, from my opinion, it should make sense to count the size of the flexible array member. I would suggest this as a enhancement of GCC to the great GCC developer.

    >
    > I doubt this is possible, as the sizeof is a property of the type, and
    > you would want it different depending on initialisation.
    > The fact that gcc compiles the code may be a bug. Are you sure, it
    > actually reserves space for the supplied values?


    Yes, I verified the space is reserved.
     
    Hill Pang, Jun 12, 2012
    #12
  13. Hill Pang

    Noob Guest

    Hill Pang wrote:

    > This is my code:
    >
    > struct f1 {
    > int x; int y[];
    > } f1 = { 1, { 2, 3, 4 } };
    >
    > void main()
    > {
    > printf("sizeof %d\n", sizeof f1);
    > }


    $ cat flexarr.c
    struct f1 {
    int x; int y[];
    } f1 = { 1, { 2, 3, 4 } };
    int main(void)
    {
    return sizeof f1;
    }

    $ gcc -std=c99 -pedantic -Wall flexarr.c
    flexarr.c:3:1: warning: initialization of a flexible array member
    flexarr.c:3:1: warning: (near initialization for 'f1.y')

    As an extension, "GCC allows static initialization of flexible array members."
    http://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
     
    Noob, Jun 12, 2012
    #13
  14. Noob <root@127.0.0.1> writes:

    > Hill Pang wrote:
    >
    >> This is my code:
    >>
    >> struct f1 {
    >> int x; int y[];
    >> } f1 = { 1, { 2, 3, 4 } };
    >>
    >> void main()
    >> {
    >> printf("sizeof %d\n", sizeof f1);
    >> }

    >
    > $ cat flexarr.c
    > struct f1 {
    > int x; int y[];
    > } f1 = { 1, { 2, 3, 4 } };
    > int main(void)
    > {
    > return sizeof f1;
    > }
    >
    > $ gcc -std=c99 -pedantic -Wall flexarr.c
    > flexarr.c:3:1: warning: initialization of a flexible array member
    > flexarr.c:3:1: warning: (near initialization for 'f1.y')
    >
    > As an extension, "GCC allows static initialization of flexible array members."
    > http://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html


    Just to clarify... It gets it right, in that the extra data is put in
    the right place (f1.y[2] == 4) but it's not considered part of the
    struct. f1.y remains incomplete and the size of that of the struct
    without the flexible array member (but including any padding that would
    be required).

    --
    Ben.
     
    Ben Bacarisse, Jun 12, 2012
    #14
  15. Hill Pang <> writes:
    > The is my code:
    >
    > struct f1 {
    > int x; int y[];
    > } f1 = { 1, { 2, 3, 4 } };
    >
    > void main()


    This should be "int main(void)".

    > {
    > printf("sizeof %d\n", sizeof f1);
    > }
    >
    > The output(by GCC) is 4.
    > My question is why it doesn't count the size of the flexible array
    > while it is static initialized? In other words, if I want to know the
    > *really* size of f1, how to do it? is it possible?


    Because that's the way it's defined by the language.

    N1570 6.7.2.1p18:

    As a special case, the last element of a structure with more
    than one named member may have an incomplete array type; this is
    called a flexible array member . In most situations, the flexible
    array member is ignored. In particular, the size of the structure
    is as if the flexible array member were omitted except that it
    may have more trailing padding than the omission would imply.

    Yes, it would be nice if sizeof yield the full size, including however
    much space is in that final array. But that would require the compiler
    to keep track of how it was allocated, and to generate run-time code
    when the size is not constant. It also would have required nailing down
    the definition in all cases.

    Flexible array members are basically a better-defined version of the
    "struct hack" (see question 2.6 of the comp.lang.c FAQ,
    <http://www.c-faq.com>).

    If you want to keep track of how many elements are in that final array,
    you'll just have to do it yourself. For example, you might add a member
    that holds the current number of elements -- and make sure that its
    value is correct at all times.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Will write code for food.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jun 12, 2012
    #15
  16. Hill Pang

    Hill Pang Guest

    On Wednesday, June 13, 2012 3:39:08 AM UTC+8, Keith Thompson wrote:
    > Hill Pang
    > writes:
    > > The is my code:
    > >
    > > struct f1 {
    > > int x; int y[];
    > > } f1 = { 1, { 2, 3, 4 } };
    > >
    > > void main()

    >
    > This should be "int main(void)".
    >
    > > {
    > > printf("sizeof %d\n", sizeof f1);
    > > }
    > >
    > > The output(by GCC) is 4.
    > > My question is why it doesn't count the size of the flexible array
    > > while it is static initialized? In other words, if I want to know the
    > > *really* size of f1, how to do it? is it possible?

    >
    > Because that's the way it's defined by the language.
    >
    > N1570 6.7.2.1p18:
    >
    > As a special case, the last element of a structure with more
    > than one named member may have an incomplete array type; this is
    > called a flexible array member . In most situations, the flexible
    > array member is ignored. In particular, the size of the structure
    > is as if the flexible array member were omitted except that it
    > may have more trailing padding than the omission would imply.
    >
    > Yes, it would be nice if sizeof yield the full size, including however
    > much space is in that final array. But that would require the compiler
    > to keep track of how it was allocated, and to generate run-time code
    > when the size is not constant. It also would have required nailing down
    > the definition in all cases.
    >
    > Flexible array members are basically a better-defined version of the
    > "struct hack" (see question 2.6 of the comp.lang.c FAQ,
    > <http://www.c-faq.com>).
    >
    > If you want to keep track of how many elements are in that final array,
    > you'll just have to do it yourself. For example, you might add a member
    > that holds the current number of elements -- and make sure that its
    > value is correct at all times.
    >
    > --
    > Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    > Will write code for food.
    > "We must do something. This is something. Therefore, we must do this."
    > -- Antony Jay and Jonathan Lynn, "Yes Minister"


    Could the allocated space be changed for a variable after it is statically initialized?
     
    Hill Pang, Jun 13, 2012
    #16
  17. Hill Pang

    Ike Naar Guest

    On 2012-06-13, Hill Pang <> wrote:
    >> Hill Pang writes:
    >> > struct f1 {
    >> > int x; int y[];
    >> > } f1 = { 1, { 2, 3, 4 } };

    >
    > Could the allocated space be changed for a variable after it is
    > statically initialized?


    No, you'd have to declare a pointer to the struct type and allocate
    space dynamically (using malloc or similar) if you want to be able
    to resize it later (using realloc).

    #include <stdlib.h>

    struct f1 {
    int x; int y[];
    };

    extern do_something(struct f1 *, int);

    int main(void)
    {
    struct f1 *pf1 = malloc(sizeof *pf1 + 3 * sizeof pf1->y[0]);
    if (pf1 != NULL)
    {
    pf1->x = 1;
    pf1->y[0] = 2;
    pf1->y[1] = 3;
    pf1->y[2] = 4;
    do_something(pf1, 3);
    struct f1 *r = realloc(pf1, sizeof *pf1 + 4 * sizeof pf1->y[0]);
    if (r != NULL)
    {
    pf1 = r;
    pf1->y[3] = 5;
    do_something(pf1, 4);
    }
    free(pf1);
    }
    return 0;
    }
     
    Ike Naar, Jun 13, 2012
    #17
    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.
Similar Threads
  1. Derek
    Replies:
    7
    Views:
    24,338
    Ron Natalie
    Oct 14, 2004
  2. Trevor

    sizeof(str) or sizeof(str) - 1 ?

    Trevor, Apr 3, 2004, in forum: C Programming
    Replies:
    9
    Views:
    633
    CBFalconer
    Apr 10, 2004
  3. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,958
    Smokey Grindel
    Dec 2, 2006
  4. Vinu
    Replies:
    13
    Views:
    1,426
    Lawrence Kirby
    May 12, 2005
  5. blufox

    sizeof( int ) != sizeof( void * )

    blufox, May 22, 2006, in forum: C Programming
    Replies:
    2
    Views:
    560
    Joe Smith
    May 22, 2006
Loading...

Share This Page