Accessing array elements within a structure

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

    Accessing array elements within a structure

    Hi folks,

    a simple question for the experts, I guess.

    Obviously I am doing something wrong when trying to access an element
    of an array declared within a structure:

    #include <stdio.h>
    #include <stddef.h>

    main() {

    const int SIZE = 2 ;

    struct test {

    long type ;
    size_t files[SIZE] ;

    } ;

    struct test example ;

    example.type = 100 ;
    example.files[0] = 2 ;

    printf("type %d - file size %lld:\n", example.type,
    example.files[0] ) ;

    }

    The "intended" output is

    type 100 - file size 2:

    but I get:

    type 100 - file size 12871933952:

    (guess I am printing a memory address or something).

    What am I doing wrong?

    Cheers


    Bernd
  • Mike Wahler

    #2
    Re: Accessing array elements within a structure


    "bernd" <bew_ba@gmx.net wrote in message
    news:1891e9d4-95f8-464c-bac5-bbaf594400e4@a1 g2000hsb.google groups.com...
    Hi folks,
    >
    a simple question for the experts, I guess.
    >
    Obviously I am doing something wrong when trying to access an element
    of an array declared within a structure:
    >
    #include <stdio.h>
    #include <stddef.h>
    >
    main() {
    >
    const int SIZE = 2 ;
    >
    struct test {
    >
    long type ;
    size_t files[SIZE] ;
    >
    } ;
    >
    struct test example ;
    >
    example.type = 100 ;
    example.files[0] = 2 ;
    >
    printf("type %d - file size %lld:\n", example.type,
    example.files[0] ) ;
    >
    }
    >
    The "intended" output is
    >
    type 100 - file size 2:
    >
    but I get:
    >
    type 100 - file size 12871933952:
    >
    (guess I am printing a memory address or something).
    >
    What am I doing wrong?
    You're using the wrong 'printf()' format specifier

    printf("type %d - file size %lu:\n", example.type,
    (unsigned long)example.fi les[0] ) ;

    -Mike


    Comment

    • Eric Sosman

      #3
      Re: Accessing array elements within a structure

      bernd wrote:
      Hi folks,
      >
      a simple question for the experts, I guess.
      >
      Obviously I am doing something wrong when trying to access an element
      of an array declared within a structure:
      >
      #include <stdio.h>
      #include <stddef.h>
      >
      main() {
      >
      const int SIZE = 2 ;
      >
      struct test {
      >
      long type ;
      size_t files[SIZE] ;
      >
      } ;
      >
      struct test example ;
      >
      example.type = 100 ;
      example.files[0] = 2 ;
      >
      printf("type %d - file size %lld:\n", example.type,
      example.files[0] ) ;
      >
      }
      >
      The "intended" output is
      >
      type 100 - file size 2:
      >
      but I get:
      >
      type 100 - file size 12871933952:
      >
      (guess I am printing a memory address or something).
      >
      What am I doing wrong?
      Using the "%lld" conversion specifier with a corresponding
      argument that is not a `long long int'.

      Since you appear to be using a C99 implementation, the
      "%zd" specifier ought to work. Or you could use whatever
      conversion strikes your fancy, explicitly converting the
      `size_t' value to the appropriate type, e.g.

      printf ("%d", (int)example.fi les[0]);

      --
      Eric.Sosman@sun .com

      Comment

      • Harald van =?UTF-8?b?RMSzaw==?=

        #4
        Re: Accessing array elements within a structure

        On Mon, 16 Jun 2008 12:44:59 -0400, Eric Sosman wrote:
        bernd wrote:
        >Hi folks,
        >>
        >a simple question for the experts, I guess.
        >>
        >Obviously I am doing something wrong when trying to access an element
        >of an array declared within a structure:
        >>
        >#include <stdio.h>
        >#include <stddef.h>
        >>
        >main() {
        >>
        > const int SIZE = 2 ;
        >>
        > struct test {
        >>
        > long type ;
        > size_t files[SIZE] ;
        >>
        > } ;
        >>
        > struct test example ;
        >>
        > example.type = 100 ;
        > example.files[0] = 2 ;
        >>
        > printf("type %d - file size %lld:\n", example.type,
        >example.file s[0] ) ;
        >>
        >}
        >[...]
        >
        Since you appear to be using a C99 implementation, [...]
        I'm curious: what makes you think this is a C99 implementation? The
        implicit int is specific to C90. The use of a const-qualified object as a
        constant expression is specific to C++. The %lld format specifier is
        specific to C99, but there's no indication that it's actually supported by
        the implementation.
        the "%zd" specifier ought to work.
        In C99, %zd can be used for the signed type corresponding to size_t, but
        there's no standard way to find out what this type is. %zu can be used in
        C99 for size_t.

        I agree with your and Mike Wahler's suggestions to use a cast, but I
        wouldn't recommend either %zd or %zu as an alternative solution without
        some more indication that it will actually work.

        Comment

        • Keith Thompson

          #5
          Re: Accessing array elements within a structure

          bernd <bew_ba@gmx.net writes:
          a simple question for the experts, I guess.
          >
          Obviously I am doing something wrong when trying to access an element
          of an array declared within a structure:
          >
          #include <stdio.h>
          #include <stddef.h>
          >
          main() {
          >
          const int SIZE = 2 ;
          >
          struct test {
          >
          long type ;
          size_t files[SIZE] ;
          >
          } ;
          >
          struct test example ;
          >
          example.type = 100 ;
          example.files[0] = 2 ;
          >
          printf("type %d - file size %lld:\n", example.type,
          example.files[0] ) ;
          >
          }
          The "%d" format requires an argument of type int; you're giving it an
          argument of type long (example.type). It happens to "work" for you,
          probably because your implementation makes int and long the same size,
          but even that doesn't guarantee anything, and it will break on other
          implementations .

          The "%lld" format requires an argument of type long long; you're
          giving it an argument of type size_t (example.files[0]).

          It's not sufficient for a format to specify a type that can hold the
          value of the corresponding argument, or one that's at least as big as
          the argument type, or even that's the same size and signedness. You
          have to match the types exactly. (There are some minor exceptions to
          this, but they're best ignored; it's easier to match the type exactly
          all the time than to remember the circumstances where you can fudge
          things a bit.)

          In C90, there's no format for size_t. C99 adds "%zu", but you might
          not have a C99 implementation (if you did, it would have been required
          to issue a diagnostic for your use of implicit int.)

          The compiler didn't complain about the mismatch because it's not
          required to. The format string is something that exists at run time;
          it could have been a variable rather than a string literal. Some
          compilers will do some format string checking for you, but in general
          you just need to get it right yourself.

          Here's how to print those values:

          printf("type %ld - file size %lu:\n",
          example.type,
          (unsigned long)example.fi les[0]);

          That's for C90, and it also works in C99 (as long as the value of
          example.files[0] doesn't happen to exceed ULLONG_MAX). Note that the
          cast is necessary to ensure that the types match exactly (this is one
          of the rare cases where a cast is necesssary and appropriate).

          If you're sure your code won't be used with a pre-C99 implementation,
          you can do this instead:

          printf("type %ld - file size %zu:\n",
          example.type,
          example.files[0]);

          But if you happen to use the above with an implementation that doesn't
          support "%zu", it's not required to tell you that it doesn't recognize
          the format.

          There are some other things you should fix that aren't relevant to
          what you were asking about.

          "main()" should be "int main(void)". The form you use can work under
          some implementations , but "int main(void)" will *always* work
          (assuming a hosted implementation rather than a freestanding
          implementation) .

          SIZE is not actually a constant; it's merely a read-only object. This
          means that if you use it as an array length, then it's a VLA
          (variable-length array). VLAs are not allowed at all in C90, and are
          not allowed as structure members even in C99. If the above compiled
          without diagnostics, then either you're using a compiler that provides
          some sort of extension (and you're invoking it in non-conforming
          mode), or you're using a C++ compiler (<OT>in C++ SIZE *is* a
          constant</OT>). You can replace your
          const int SIZE = 2 ;
          with
          #define SIZE 2

          You should add "return 0;" before the closing '}'. There are
          circumstances where it's not necessary, but this is another case where
          it's easier to use something that's universally valid than to keep
          track of the cases where you can get away with something else. main
          returns an int, so you should return an int; 0 is a safe value.

          Finally, a style point. I personally dislike white space before a
          semicolon. The compiler doesn't care, of course, and some programmers
          will disagree with me, but I think most people write semicolons with
          no preceding blank.

          Here's your program as I would have written it (I've taken the liberty
          of changing the output format a bit):

          #include <stdio.h>
          #include <stddef.h>

          int main(void)
          {

          #define SIZE 2

          struct test {
          long type;
          size_t files[SIZE];
          };

          struct test example;

          example.type = 100;
          example.files[0] = 2;

          printf("example .type = %ld, example.files[0] = %lu\n",
          example.type, (unsigned long)example.fi les[0]);

          return 0;
          }

          --
          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

          • Eric Sosman

            #6
            Re: Accessing array elements within a structure

            Harald van Dijk wrote:
            On Mon, 16 Jun 2008 12:44:59 -0400, Eric Sosman wrote:
            >bernd wrote:
            >>Hi folks,
            >>>
            >>a simple question for the experts, I guess.
            >>>
            >>Obviously I am doing something wrong when trying to access an element
            >>of an array declared within a structure:
            >>>
            >>#include <stdio.h>
            >>#include <stddef.h>
            >>>
            >>main() {
            >>>
            >> const int SIZE = 2 ;
            >>>
            >> struct test {
            >>>
            >> long type ;
            >> size_t files[SIZE] ;
            >>>
            >> } ;
            >>>
            >> struct test example ;
            >>>
            >> example.type = 100 ;
            >> example.files[0] = 2 ;
            >>>
            >> printf("type %d - file size %lld:\n", example.type,
            >>example.fil es[0] ) ;
            >>>
            >>}
            >>[...]
            > Since you appear to be using a C99 implementation, [...]
            >
            I'm curious: what makes you think this is a C99 implementation? The
            implicit int is specific to C90. The use of a const-qualified object as a
            constant expression is specific to C++. The %lld format specifier is
            specific to C99, but there's no indication that it's actually supported by
            the implementation.
            The variable-length array was the clue I fastened on. The
            alternative explanation that he's actually using That Other
            Language didn't occur to me (because I have irrational prejudices
            about TOL and prefer to think about it as little as possible).
            Besides, he couldn't *possibly* be using TOL because if he were
            he'd have posted his question in c.l.c++ instead of here, right?
            >the "%zd" specifier ought to work.
            >
            In C99, %zd can be used for the signed type corresponding to size_t, but
            there's no standard way to find out what this type is. %zu can be used in
            C99 for size_t.
            Right; good catch.

            --
            Eric.Sosman@sun .com

            Comment

            • Keith Thompson

              #7
              Re: Accessing array elements within a structure

              Eric Sosman <Eric.Sosman@su n.comwrites:
              Harald van Dijk wrote:
              >On Mon, 16 Jun 2008 12:44:59 -0400, Eric Sosman wrote:
              >>bernd wrote:
              [...]
              >>> const int SIZE = 2 ;
              >>>>
              >>> struct test {
              >>>>
              >>> long type ;
              >>> size_t files[SIZE] ;
              >>>>
              >>> } ;
              [...]
              >> Since you appear to be using a C99 implementation, [...]
              >I'm curious: what makes you think this is a C99 implementation? The
              >implicit int is specific to C90. The use of a const-qualified object
              >as a constant expression is specific to C++. The %lld format
              >specifier is specific to C99, but there's no indication that it's
              >actually supported by the implementation.
              >
              The variable-length array was the clue I fastened on.
              [...]

              C99 doesn't allow VLAs as struct members. C99 6.7.2.1p8:

              A member of a structure or union may have any object type other
              than a variably modified type.

              I note that the original program compiles without diagnostics using
              gcc with no options (i.e., in a mode that doesn't conform to any C
              standard).

              --
              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

              • Richard Tobin

                #8
                Re: Accessing array elements within a structure

                In article <lnej6xb8na.fsf @nuthaus.mib.or g>,
                Keith Thompson <kst-u@mib.orgwrote:
                >I note that the original program compiles without diagnostics using
                >gcc with no options
                And does so even if SIZE is not declared const, and even allows this:

                scanf("%d", &SIZE);

                struct test2 {
                long type ;
                size_t files[SIZE] ;
                } ;

                producing a struct whose size depends on the value of SIZE when the
                declaration is encountered.

                -- Richard
                --
                In the selection of the two characters immediately succeeding the numeral 9,
                consideration shall be given to their replacement by the graphics 10 and 11 to
                facilitate the adoption of the code in the sterling monetary area. (X3.4-1963)

                Comment

                • rahul

                  #9
                  Re: Accessing array elements within a structure

                  On Jun 16, 10:43 pm, rich...@cogsci. ed.ac.uk (Richard Tobin) wrote:
                  In article <lnej6xb8na.... @nuthaus.mib.or g>,
                  Keith Thompson <ks...@mib.orgw rote:
                  >
                  I note that the original program compiles without diagnostics using
                  gcc with no options
                  >
                  And does so even if SIZE is not declared const, and even allows this:
                  >
                  scanf("%d", &SIZE);
                  >
                  struct test2 {
                  long type ;
                  size_t files[SIZE] ;
                  } ;
                  >
                  producing a struct whose size depends on the value of SIZE when the
                  declaration is encountered.
                  >
                  -- Richard
                  --
                  In the selection of the two characters immediately succeeding the numeral 9,
                  consideration shall be given to their replacement by the graphics 10 and 11 to
                  facilitate the adoption of the code in the sterling monetary area. (X3.4-1963)
                  gcc has supported variable length arrays for a long time. Actually
                  many notable systems(linux kernel) has been written in GNU C. Some of
                  them has made it to C99(variable length arrays, inline functions).
                  <off-topic>
                  Why is it that the structure could not contain variable length arrays?
                  </off-topic>

                  Comment

                  • Ben Bacarisse

                    #10
                    Re: Accessing array elements within a structure

                    rahul <rahulsinner@gm ail.comwrites:
                    On Jun 16, 10:43 pm, rich...@cogsci. ed.ac.uk (Richard Tobin) wrote:
                    >In article <lnej6xb8na.... @nuthaus.mib.or g>,
                    >Keith Thompson <ks...@mib.orgw rote:
                    >>
                    >I note that the original program compiles without diagnostics using
                    >gcc with no options
                    >>
                    >And does so even if SIZE is not declared const, and even allows this:
                    >>
                    > scanf("%d", &SIZE);
                    >>
                    > struct test2 {
                    > long type ;
                    > size_t files[SIZE] ;
                    > } ;
                    >>
                    >producing a struct whose size depends on the value of SIZE when the
                    >declaration is encountered.
                    <snip sig>

                    Best not to quote sig blocks.
                    gcc has supported variable length arrays for a long time. Actually
                    many notable systems(linux kernel) has been written in GNU C. Some of
                    them has made it to C99(variable length arrays, inline functions).
                    But just in case you or anyone else is confused, *this* kind of
                    variable length array did *not* get into C99. The form sanctioned by
                    the standard is to allow the last member of a struct to be an array
                    with no size size:

                    struct test {
                    long type;
                    size_t files[];
                    };

                    -- a formalising of the old "struct hack". Of course, there are other
                    VLAs in C99 (as automatic storage and as function parameters) which
                    work differently.

                    --
                    Ben.

                    Comment

                    • CBFalconer

                      #11
                      Re: Accessing array elements within a structure

                      rahul wrote:
                      >
                      .... snip ...
                      >
                      gcc has supported variable length arrays for a long time. Actually
                      many notable systems(linux kernel) has been written in GNU C. Some of
                      them has made it to C99(variable length arrays, inline functions).
                      Not if you tell gcc to compile C, rather than the non-standard
                      gnu-C. This requires using -ansi -pedantic in the command string.
                      Combined with -W -Wall you will have most portability affecting
                      source errors exposed.

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


                      ** Posted from http://www.teranews.com **

                      Comment

                      • Harald van =?UTF-8?b?RMSzaw==?=

                        #12
                        Re: Accessing array elements within a structure

                        On Tue, 17 Jun 2008 02:50:50 -0400, CBFalconer wrote:
                        rahul wrote:
                        >>
                        ... snip ...
                        >>
                        >gcc has supported variable length arrays for a long time. Actually many
                        >notable systems(linux kernel) has been written in GNU C. Some of them
                        >has made it to C99(variable length arrays, inline functions).
                        >
                        Not if you tell gcc to compile C, rather than the non-standard gnu-C.
                        Er... if you tell gcc to compile C, extensions to C90 available in GNU C
                        will disappear from the C99 standard? Your message does not make sense as
                        a reply to the text you have quoted. On re-reading, I assume you meant it
                        as a reply to the first sentence only, but then it's simply wrong. gcc
                        supports variable-length arrays in C90-conforming mode as well.

                        Comment

                        • CBFalconer

                          #13
                          Re: Accessing array elements within a structure

                          Harald van D?k wrote:
                          CBFalconer wrote:
                          >rahul wrote:
                          >>
                          >... snip ...
                          >>
                          >>gcc has supported variable length arrays for a long time. Actually
                          >>many notable systems(linux kernel) has been written in GNU C. Some
                          >>of them has made it to C99(variable length arrays, inline functions).
                          >>
                          >Not if you tell gcc to compile C, rather than the non-standard gnu-C.
                          >----------------- elided from qupte ---------------
                          >gnu-C. This requires using -ansi -pedantic in the command string.
                          >Combined with -W -Wall you will have most portability affecting
                          >source errors exposed.
                          >------------------ end of elision -----------------
                          >
                          Er... if you tell gcc to compile C, extensions to C90 available
                          in GNU C will disappear from the C99 standard? Your message does
                          not make sense as a reply to the text you have quoted. On re-
                          reading, I assume you meant it as a reply to the first sentence
                          only, but then it's simply wrong. gcc supports variable-length
                          arrays in C90-conforming mode as well.
                          You snipped a portion of my reply, re-inserted above. Note the
                          '-ansi' component in the command string. This selects C90/C95 mode
                          for gcc, not c99 mode. C99 mode requires replacing the '-ansi'
                          with '-std=C99'.

                          Please don't snip within paragraphs.

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


                          ** Posted from http://www.teranews.com **

                          Comment

                          • Harald van =?UTF-8?b?RMSzaw==?=

                            #14
                            Re: Accessing array elements within a structure

                            On Wed, 18 Jun 2008 18:17:05 -0400, CBFalconer wrote:
                            Harald van D?k wrote:
                            >CBFalconer wrote:
                            >>rahul wrote:
                            >>>
                            >>... snip ...
                            >>>
                            >>>gcc has supported variable length arrays for a long time. Actually
                            >>>many notable systems(linux kernel) has been written in GNU C. Some of
                            >>>them has made it to C99(variable length arrays, inline functions).
                            >>>
                            >>Not if you tell gcc to compile C, rather than the non-standard gnu-C.
                            >
                            >>----------------- elided from qupte --------------- gnu-C. This
                            >>requires using -ansi -pedantic in the command string. Combined with -W
                            >>-Wall you will have most portability affecting source errors exposed.
                            >>------------------ end of elision -----------------
                            >>
                            >Er... if you tell gcc to compile C, extensions to C90 available in GNU
                            >C will disappear from the C99 standard? Your message does not make
                            >sense as a reply to the text you have quoted. On re- reading, I assume
                            >you meant it as a reply to the first sentence only, but then it's
                            >simply wrong. gcc supports variable-length arrays in C90-conforming
                            >mode as well.
                            >
                            You snipped a portion of my reply, re-inserted above.
                            Yes, I snipped a portion of your reply that I didn't respond to and that
                            wasn't required to follow my message.
                            Note the '-ansi'
                            component in the command string. This selects C90/C95 mode for gcc, not
                            c99 mode.
                            Yes, I am aware of that. Notice how I wrote gcc supports variable-length
                            arrays in C90-conforming mode, and didn't write anything about C99-
                            conforming mode? You are wrong about C90-conforming mode. gcc, with the
                            command-line options you gave, supports variable-length arrays.
                            C99 mode requires replacing the '-ansi' with '-std=C99'.
                            -std=c99, not C99.
                            Please don't snip within paragraphs.
                            I damn well will when it makes the message easier to follow. You decided
                            not to snip in the paragraph from rahul's message, and that made your
                            message hard to read.

                            Comment

                            • Antoninus Twink

                              #15
                              Re: Accessing array elements within a structure

                              On 19 Jun 2008 at 5:24, Harald van Dijk wrote:
                              On Wed, 18 Jun 2008 18:17:05 -0400, CBFalconer wrote:
                              >Please don't snip within paragraphs.
                              >
                              I damn well will when it makes the message easier to follow.
                              *blink*

                              I know CBF would try the patience of a saint, but to provoke Harold
                              (who usually comes across as a bit like a compiler in human form) to a
                              display of annoyance is quite an achievement.

                              We'll know CBF has really made it if he manages to get under the skin of
                              Chris Torek...

                              Comment

                              Working...