c size 0 question

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • sinbad

    c size 0 question

    chip_init.c

    1 #include <stdio.h>
    2 struct a {
    3 char buf[0];
    4 }b;
    5 struct c {
    6 char buf[1];
    7 }d;
    8
    9 int main ()
    10 {
    11 printf("%u %u\n", sizeof(b), sizeof(d));
    12 printf("%u %u", sizeof(struct a), sizeof(struct c));
    13 return 0;
    14 }

    the output is
    0 1
    0 1

    can someone explain why sizeof(b) and sizeof(struct a) is zero,
    if there is no memory allocated how can i use this variable
    and why gcc allows this.

    thanks
    ~
  • Joachim Schmitz

    #2
    Re: c size 0 question

    sinbad wrote:
    chip_init.c
    >
    1 #include <stdio.h>
    2 struct a {
    3 char buf[0];
    4 }b;
    5 struct c {
    6 char buf[1];
    7 }d;
    8
    9 int main ()
    10 {
    11 printf("%u %u\n", sizeof(b), sizeof(d));
    12 printf("%u %u", sizeof(struct a), sizeof(struct c));
    13 return 0;
    14 }
    >
    the output is
    0 1
    0 1
    >
    can someone explain why sizeof(b) and sizeof(struct a) is zero,
    if there is no memory allocated how can i use this variable
    and why gcc allows this.
    Most propbably because you didn't incoke gcc in a (mostly) conforming mode
    (-ansi or -std=c99 plus -pedantic)

    Bye, Jojo

    Comment

    • Nate Eldredge

      #3
      Re: c size 0 question

      sinbad <sinbad.sinbad@ gmail.comwrites :
      chip_init.c
      >
      1 #include <stdio.h>
      2 struct a {
      3 char buf[0];
      4 }b;
      5 struct c {
      6 char buf[1];
      7 }d;
      8
      9 int main ()
      10 {
      11 printf("%u %u\n", sizeof(b), sizeof(d));
      12 printf("%u %u", sizeof(struct a), sizeof(struct c));
      13 return 0;
      14 }
      >
      the output is
      0 1
      0 1
      >
      can someone explain why sizeof(b) and sizeof(struct a) is zero,
      if there is no memory allocated how can i use this variable
      and why gcc allows this.
      It's a GCC extension, not part of standard C. You can read about it in
      the GCC manual at
      http://gcc.gnu.org/onlinedocs/gcc-4....ro-Length.html . That
      page also has an explanation of C99 flexible array members, which are
      similar and standard.

      Note that your program has a bug; the "%u" format specifier for printf()
      expects you to pass an unsigned int, but sizeof(b) has type size_t,
      which might be different. You should ideally use the C99-standard "%z"
      format specifier if your library supports it. Otherwise, cast sizeof(b)
      to unsigned int, and hope that it fits.

      Also, the correctness of `int main()' is controversial. You should
      really use `int main(void)' which is unambiguously correct.

      Comment

      • James Kuyper

        #4
        Re: c size 0 question

        Nate Eldredge wrote:
        ....
        Note that your program has a bug; the "%u" format specifier for printf()
        expects you to pass an unsigned int, but sizeof(b) has type size_t,
        which might be different. You should ideally use the C99-standard "%z"
        format specifier if your library supports it. Otherwise, cast sizeof(b)
        to unsigned int, and hope that it fits.
        It's safer to use unsigned long; that's more likely to fit.

        Comment

        • James Kuyper

          #5
          Re: c size 0 question

          sinbad wrote:
          chip_init.c
          >
          1 #include <stdio.h>
          2 struct a {
          3 char buf[0];
          It's a constraint violation to declare an array with a length of 0. gcc
          allows this as an extension, but it's entirely up to gcc to determine
          how it can be used.
          4 }b;
          5 struct c {
          6 char buf[1];
          7 }d;
          8
          9 int main ()
          10 {
          11 printf("%u %u\n", sizeof(b), sizeof(d));
          The "%u" specifier expects an unsigned int argument; the result of the
          sizeof operator is size_t, which is unsigned, but might be an unsigned
          type larger than unsigned int (it could also be smaller, though that's a
          lot less likely, and not a problem in this context).

          In C90, you should write
          printf("%lu %lu\n",
          (unsigned long)sizeof b, (unsigned long)sizeof d);

          In C99, you should write
          printf("%z %z\n", sizeof b, sizeof d);

          Comment

          • Nick Keighley

            #6
            Re: c size 0 question

            On 21 Nov, 08:13, Nate Eldredge <n...@vulcan.la nwrote:

            <snip>
            Also, the correctness of `int main()' is controversial.  You should
            really use `int main(void)' which is unambiguously correct
            I'm not sure if "controvers ial" is the right word.

            int main()

            in a function definition is correct and unambiguous.

            int main (void)

            is more of a style thing

            --
            Nick Keighley

            Comment

            • Keith Thompson

              #7
              Re: c size 0 question

              Nate Eldredge <nate@vulcan.la nwrites:
              [...]
              Note that your program has a bug; the "%u" format specifier for printf()
              expects you to pass an unsigned int, but sizeof(b) has type size_t,
              which might be different. You should ideally use the C99-standard "%z"
              format specifier if your library supports it.
              You mean "%zu".
              Otherwise, cast sizeof(b)
              to unsigned int, and hope that it fits.
              Even better, cast to unsigned long and use "%lu" -- though unsigned
              int is fine if you're sure the size doesn't exceed 32767.
              [...]

              --
              Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
              Nokia
              "We must do something. This is something. Therefore, we must do this."
              -- Antony Jay and Jonathan Lynn, "Yes Minister"

              Comment

              • Keith Thompson

                #8
                Re: c size 0 question

                Nick Keighley <nick_keighley_ nospam@hotmail. comwrites:
                On 21 Nov, 08:13, Nate Eldredge <n...@vulcan.la nwrote:
                <snip>
                >
                >Also, the correctness of `int main()' is controversial.  You should
                >really use `int main(void)' which is unambiguously correct
                >
                I'm not sure if "controvers ial" is the right word.
                >
                int main()
                >
                in a function definition is correct and unambiguous.
                >
                int main (void)
                >
                is more of a style thing
                It is controversial; we've discussed it here at considerable length a
                couple of times. In case you missed it, the argument is that
                int main() { /* ... */ }
                is not "equivalent " to
                int main(void) { /* ... */ }
                because the latter causes a call main(42) to be a constraint
                violation.

                See, for example,


                starting at the 10th article.

                --
                Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                Nokia
                "We must do something. This is something. Therefore, we must do this."
                -- Antony Jay and Jonathan Lynn, "Yes Minister"

                Comment

                • Keith Thompson

                  #9
                  Re: c size 0 question

                  James Kuyper <jameskuyper@ve rizon.netwrites :
                  [...]
                  The "%u" specifier expects an unsigned int argument; the result of the
                  sizeof operator is size_t, which is unsigned, but might be an unsigned
                  type larger than unsigned int (it could also be smaller, though that's
                  a lot less likely, and not a problem in this context).
                  >
                  In C90, you should write
                  printf("%lu %lu\n",
                  (unsigned long)sizeof b, (unsigned long)sizeof d);
                  >
                  In C99, you should write
                  printf("%z %z\n", sizeof b, sizeof d);
                  printf("%zu %zu\n", sizeof b, sizeof d);

                  --
                  Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                  Nokia
                  "We must do something. This is something. Therefore, we must do this."
                  -- Antony Jay and Jonathan Lynn, "Yes Minister"

                  Comment

                  • s0suk3@gmail.com

                    #10
                    Re: c size 0 question

                    On Nov 21, 11:01 am, Keith Thompson <kst-u@mib.orgwrote:
                    Nick Keighley <nick_keighley_ nospam@hotmail. comwrites:
                    On 21 Nov, 08:13, Nate Eldredge <n...@vulcan.la nwrote:
                    <snip>
                    >
                    Also, the correctness of `int main()' is controversial.  You should
                    really use `int main(void)' which is unambiguously correct
                    >
                    I'm not sure if "controvers ial" is the right word.
                    >
                       int main()
                    >
                    in a function definition is correct and unambiguous.
                    >
                       int main (void)
                    >
                    is more of a style thing
                    >
                    It is controversial; we've discussed it here at considerable length a
                    couple of times.  In case you missed it, the argument is that
                        int main() { /* ... */ }
                    is not "equivalent " to
                        int main(void) { /* ... */ }
                    because the latter causes a call main(42) to be a constraint
                    violation.
                    Why? In the link to the first thread you posted below, Richard
                    Heathfield posted a quote from C89 about this. In 6.7.5.3 from C99,
                    the quote is:

                    "14 An identifier list declares only the identifiers of the parameters
                    of the function. An empty list in a function declarator that is part
                    of a definition of that function specifies that the
                    function has no parameters. The empty list in a function declarator
                    that is not part of a
                    definition of that function specifies that no information about the
                    number or types of the
                    parameters is supplied.126)"

                    So if the function declarator is part of the definition of the
                    function (as was the case for main() in the OP's code), then calling
                    main(42) *is* a constraint violation, isn't it?

                    Sebastian

                    Comment

                    • CBFalconer

                      #11
                      Re: c size 0 question

                      James Kuyper wrote:
                      sinbad wrote:
                      >
                      >chip_init.c
                      >>
                      > 1 #include <stdio.h>
                      > 2 struct a {
                      > 3 char buf[0];
                      >
                      It's a constraint violation to declare an array with a length of
                      0. gcc allows this as an extension, but it's entirely up to gcc
                      to determine how it can be used.
                      You can define the last element of a struct as a zero sized array,
                      in C99 only. This allows special games to set the buf (above) to
                      an appropriate size on malloc of an instance of that struct.

                      Other possibilities are off-topic extensions.

                      --
                      [mail]: Chuck F (cbfalconer at maineline dot net)
                      [page]: <http://cbfalconer.home .att.net>
                      Try the download section.

                      Comment

                      • Keith Thompson

                        #12
                        Re: c size 0 question

                        CBFalconer <cbfalconer@yah oo.comwrites:
                        James Kuyper wrote:
                        >sinbad wrote:
                        >>
                        >>chip_init.c
                        >>>
                        >> 1 #include <stdio.h>
                        >> 2 struct a {
                        >> 3 char buf[0];
                        >>
                        >It's a constraint violation to declare an array with a length of
                        >0. gcc allows this as an extension, but it's entirely up to gcc
                        >to determine how it can be used.
                        >
                        You can define the last element of a struct as a zero sized array,
                        in C99 only. This allows special games to set the buf (above) to
                        an appropriate size on malloc of an instance of that struct.
                        [...]

                        No, C99's flexible array member syntax doesn't use "[0]"; it uses
                        "[]".

                        So this:

                        struct a {
                        size_t len;
                        char buf[1];
                        };

                        is likely to be a C90-style struct hack (whose legality has been
                        questioned); and this:

                        struct b {
                        size_t len;
                        char buf[0];
                        };

                        is a constraint violation in either C90 or C99, and is likely to be
                        dependent on a gcc extension; and this:

                        struct c {
                        size_t len;
                        char buf[];
                        };

                        is a struct containing a C99 flexible array member, intended to
                        replace the struct hack.

                        See also question 2.6 in the comp.lang.c FAQ, <http://c-faq.com/>
                        (which unfortunately doesn't mention the phrase "struct hack" except
                        in its URL).

                        --
                        Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                        Nokia
                        "We must do something. This is something. Therefore, we must do this."
                        -- Antony Jay and Jonathan Lynn, "Yes Minister"

                        Comment

                        Working...