type of array index?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • shmartonak@ticnet.com

    #1

    type of array index?


    For maximum portability what should the type of an array index be? Can
    any integer type be used safely? Or should I only use an unsigned type?
    Or what?

    If I'm using pointers to access array elements as *(mptr+k) where I've
    declared

    MYTYPE *mptr;

    what should be the type of 'k'? Should it be ptrdiff_t?

    OT: near as I can tell my implementation of gcc doesn't have an
    <stddef.h> file with ptrdiff_t defined. Am I overlooking something?

    --


  • Jonathan Bartlett

    #2
    Re: type of array index?

    > what should be the type of 'k'? Should it be ptrdiff_t?

    It should be any type of integer.

    Jon
    ----
    Learn to program using Linux assembly language

    Comment

    • Jonathan Bartlett

      #3
      Re: type of array index?

      If you really want ptrdiff_t, it appears to be in malloc.h. stdint.h
      has its limits. Interestingly, obstack.h thinks that it appears in
      stddef.h, too. Perhaps someone should report that to the maintainers.
      Using gcc 3.3.1.

      Jon
      ----
      Learn to program using Linux assembly language

      Comment

      • Michael Mair

        #4
        Re: type of array index?

        shmartonak@ticn et.com wrote:[color=blue]
        > For maximum portability what should the type of an array index be? Can
        > any integer type be used safely? Or should I only use an unsigned type?
        > Or what?[/color]

        Essentially, there are two choices:
        1. Use int whenever sufficient, use a wider type when necessary.
        Sufficient means sufficient with respect to the minimal requirements
        from the standard.
        2. Always use size_t.
        size_t is sufficient for all arrays and for indexing all storage you
        can allocate (bytewise).

        Personally, I favor the second approach but I am not religious
        about it. Drawbacks: You have to be more careful due to the inherent
        nonnegativity of the index type, e.g.
        for (i=MAX-1; i>=0; i--)
        operation_on(ar ray[i]);
        either has to become
        for (i=MAX; i>0; i--)
        operation_on(ar ray[i-1]);
        or
        for (i=MAX-1; i!=-1; i--)
        operation_on(ar ray[i]);
        which I like better.
        As for int: It is possible that int indices are "faster" as int usually
        is the "natural" integer type of the system but if this is really
        the case, one can still optimise where necessary. Undefined behaviour
        due to forgetting about "old-fashioned" 16 bit ints and resulting
        strange errors are less nice.

        However, there have been many discussions about that.
        Do as you like and look for range/sanity checks as necessary (in both
        cases).

        [color=blue]
        > If I'm using pointers to access array elements as *(mptr+k) where I've
        > declared
        >
        > MYTYPE *mptr;
        >
        > what should be the type of 'k'? Should it be ptrdiff_t?[/color]

        Any integer type which suffices for your range requirements.
        I would use ptrdiff_t only where appropriate.

        If ssize_t had made it into the standard, I'd suggest that.

        [color=blue]
        > OT: near as I can tell my implementation of gcc doesn't have an
        > <stddef.h> file with ptrdiff_t defined. Am I overlooking something?[/color]

        That you cannot find it in the header file does not mean that
        it is not there by some magic (or simply comes in from another
        included file).

        Just try it out:
        If

        #include <stddef.h>
        int main (void) { int a[3]; ptrdiff_t b = (a+2)-(a+1); return 0; }

        does not compile, file a bug report.
        If it does compile without the #include, do the same.


        Cheers
        Michael
        --
        E-Mail: Mine is an /at/ gmx /dot/ de address.

        Comment

        • Michael Mair

          #5
          Re: type of array index?

          Jonathan Bartlett wrote:[color=blue]
          > If you really want ptrdiff_t, it appears to be in malloc.h. stdint.h[/color]

          malloc.h is not a C standard header, thus offtopic.
          [color=blue]
          > has its limits. Interestingly, obstack.h thinks that it appears in[/color]

          dito for obstack.h
          [color=blue]
          > stddef.h, too. Perhaps someone should report that to the maintainers.
          > Using gcc 3.3.1.[/color]

          If including <stddef.h> has the effect that size_t or ptrdiff_t
          are available when they were not before, everything is fine:
          The implementation may do each and everything behind the scenes.

          I did not yet have any problems with gcc's compliance in _this_
          respect.


          Cheers
          Michael
          --
          E-Mail: Mine is an /at/ gmx /dot/ de address.

          Comment

          • Andrey Tarasevich

            #6
            Re: type of array index?

            shmartonak@ticn et.com wrote:[color=blue]
            > For maximum portability what should the type of an array index be? Can
            > any integer type be used safely? Or should I only use an unsigned type?
            > Or what?
            >
            > If I'm using pointers to access array elements as *(mptr+k) where I've
            > declared
            >
            > MYTYPE *mptr;
            >
            > what should be the type of 'k'? Should it be ptrdiff_t?[/color]

            It depends.

            In concrete (non-generic) code the type is usually dictated by the
            natural properties of the application area. You should normally have a
            type that designates the total amount of objects of 'MYTYPE' already.
            This type is an obvious candidate for the array index type. For example,
            if this is an array of, say, file handles and you use 'unsigned short'
            object to store the total number of files, then 'unsigned short' would
            be a natural choice for the index type for this array. This, of course,
            applies only if you don't care about negative indexing. For negative
            indexing you'd have to use either 'short' or 'int', depending on the
            required range.

            In generic code 'ptrdiff_t' is the first candidate for array index type,
            which also supports negative indices. If you don't care about negative
            indices or you want to emphasize the fact that negative indices are not
            allowed in some context, then you might want to go with 'size_t'. This
            unsigned type is large enough for indexing of any array.

            However, from the pedantic point of view, 'size_t' is intended to
            implement a concept of "object size", while array index is more related
            to the concept of "container element count". These two concepts are not
            related and using 'size_t' for array indexing is a conceptual error. It
            might be more elegant to "hide" the 'size_t' behind a typedef name as
            follows

            typedef size_t pos_ptrdiff_t;

            and use 'pos_ptrdiff_t' for generic non-negative array indexing.

            --
            Best regards,
            Andrey Tarasevich

            Comment

            • Michael Mair

              #7
              Re: type of array index?

              Andrey Tarasevich wrote:[color=blue]
              > shmartonak@ticn et.com wrote:
              >[color=green]
              >>For maximum portability what should the type of an array index be? Can
              >>any integer type be used safely? Or should I only use an unsigned type?
              >>Or what?
              >>
              >>If I'm using pointers to access array elements as *(mptr+k) where I've
              >>declared
              >>
              >> MYTYPE *mptr;
              >>
              >>what should be the type of 'k'? Should it be ptrdiff_t?[/color]
              >
              >
              > It depends.
              >
              > In concrete (non-generic) code the type is usually dictated by the
              > natural properties of the application area. You should normally have a
              > type that designates the total amount of objects of 'MYTYPE' already.
              > This type is an obvious candidate for the array index type. For example,
              > if this is an array of, say, file handles and you use 'unsigned short'
              > object to store the total number of files, then 'unsigned short' would
              > be a natural choice for the index type for this array. This, of course,
              > applies only if you don't care about negative indexing. For negative
              > indexing you'd have to use either 'short' or 'int', depending on the
              > required range.
              >
              > In generic code 'ptrdiff_t' is the first candidate for array index type,
              > which also supports negative indices. If you don't care about negative
              > indices or you want to emphasize the fact that negative indices are not
              > allowed in some context, then you might want to go with 'size_t'. This
              > unsigned type is large enough for indexing of any array.
              >
              > However, from the pedantic point of view, 'size_t' is intended to
              > implement a concept of "object size", while array index is more related
              > to the concept of "container element count". These two concepts are not
              > related and using 'size_t' for array indexing is a conceptual error. It
              > might be more elegant to "hide" the 'size_t' behind a typedef name as
              > follows
              >
              > typedef size_t pos_ptrdiff_t;
              >
              > and use 'pos_ptrdiff_t' for generic non-negative array indexing.[/color]

              Nicely put.
              Something for a confessing size_t-user like me to think about :-)
              Grabbed and stored.

              Cheers
              Michael
              --
              E-Mail: Mine is an /at/ gmx /dot/ de address.

              Comment

              • Keith Thompson

                #8
                Re: type of array index?

                Jonathan Bartlett <johnnyb@eskimo .com> writes:[color=blue]
                > If you really want ptrdiff_t, it appears to be in malloc.h. stdint.h
                > has its limits. Interestingly, obstack.h thinks that it appears in
                > stddef.h, too. Perhaps someone should report that to the
                > maintainers. Using gcc 3.3.1.[/color]

                ptrdiff_t is declared in <stddef.h>. <malloc.h> is not a standard
                header (the malloc() function is declared in <stdlib.h>), nor is
                <obstack.h>. And <stdint.h> is a standard header in C99, but not in
                C90, so not all current implementations will provide it (though it's
                not too difficult to roll your own).

                --
                Keith Thompson (The_Other_Keit h) kst-u@mib.org <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.

                Comment

                • those who know me have no need of my name

                  #9
                  Re: type of array index?

                  in comp.lang.c i read:
                  [color=blue]
                  >OT: near as I can tell my implementation of gcc doesn't have an
                  ><stddef.h> file with ptrdiff_t defined. Am I overlooking something?[/color]

                  there is no requirement by the standard that a file exist -- it's allowed
                  to be magical, perhaps entirely internal. though in fact it does exist,
                  it's just that it's not where you are looking.

                  --
                  a signature

                  Comment

                  • Stephen Sprunk

                    #10
                    Re: type of array index?

                    "Andrey Tarasevich" <andreytarasevi ch@hotmail.com> wrote in message
                    news:114629s61t kmk74@news.supe rnews.com...[color=blue]
                    > shmartonak@ticn et.com wrote:[color=green]
                    > > For maximum portability what should the type of an array index be? Can
                    > > any integer type be used safely? Or should I only use an unsigned type?
                    > > Or what?
                    > >
                    > > If I'm using pointers to access array elements as *(mptr+k) where I've
                    > > declared
                    > >
                    > > MYTYPE *mptr;
                    > >
                    > > what should be the type of 'k'? Should it be ptrdiff_t?[/color]
                    >
                    > It depends.[/color]
                    ....[color=blue]
                    > In generic code 'ptrdiff_t' is the first candidate for array index type,
                    > which also supports negative indices. If you don't care about negative
                    > indices or you want to emphasize the fact that negative indices are not
                    > allowed in some context, then you might want to go with 'size_t'. This
                    > unsigned type is large enough for indexing of any array.
                    >
                    > However, from the pedantic point of view, 'size_t' is intended to
                    > implement a concept of "object size", while array index is more related
                    > to the concept of "container element count". These two concepts are not
                    > related and using 'size_t' for array indexing is a conceptual error.[/color]

                    Since an array is an object, and size_t is defined to be large enough to
                    represent the size of any object, size_t naturally must be able to represent
                    any possible array subscript.

                    In _The Standard C Library_, P. J. Plauger writes:

                    "Unlike ptrdiff_t, however, size_t is /very/ useful. It is the safest type
                    to represent any integer data object you use as an array subscript. You
                    don't have to worry if a small array evolves into a very large one as the
                    program changes. Subscript arithmetic will never overflow when performed in
                    type size_t." and "You should make a point of using type size_t /anywhere/
                    your program performs array subscripting or address arithmetic." (emphasis
                    in original)

                    The only reason one might prefer ptrdiff_t for array subscripts is where,
                    due to looping, you need the ability to count down past zero. In this case,
                    I would prefer ssize_t (where available) over ptrdiff_t, but first I'd
                    consider whether it was feasible to restructure the loop condition such that
                    a signed subscript wasn't needed.

                    S

                    --
                    Stephen Sprunk "Stupid people surround themselves with smart
                    CCIE #3723 people. Smart people surround themselves with
                    K5SSS smart people who disagree with them." --Aaron Sorkin

                    Comment

                    • Andrey Tarasevich

                      #11
                      Re: type of array index?

                      Stephen Sprunk wrote:[color=blue][color=green][color=darkred]
                      >> > For maximum portability what should the type of an array index be? Can
                      >> > any integer type be used safely? Or should I only use an unsigned type?
                      >> > Or what?
                      >> >
                      >> > If I'm using pointers to access array elements as *(mptr+k) where I've
                      >> > declared
                      >> >
                      >> > MYTYPE *mptr;
                      >> >
                      >> > what should be the type of 'k'? Should it be ptrdiff_t?[/color]
                      >>
                      >> It depends.[/color]
                      > ...[color=green]
                      >> In generic code 'ptrdiff_t' is the first candidate for array index type,
                      >> which also supports negative indices. If you don't care about negative
                      >> indices or you want to emphasize the fact that negative indices are not
                      >> allowed in some context, then you might want to go with 'size_t'. This
                      >> unsigned type is large enough for indexing of any array.
                      >>
                      >> However, from the pedantic point of view, 'size_t' is intended to
                      >> implement a concept of "object size", while array index is more related
                      >> to the concept of "container element count". These two concepts are not
                      >> related and using 'size_t' for array indexing is a conceptual error.[/color]
                      >
                      > Since an array is an object, and size_t is defined to be large enough to
                      > represent the size of any object, size_t naturally must be able to represent
                      > any possible array subscript.[/color]

                      That's the very reason why I suggest using 'size_t' for array indexing
                      in generic context. For example, in a generic array-support library.

                      At application level there's rarely a need to have an array just for the
                      sake of having an array. What is normally needed at application level is
                      a container with index-based random-access interface. This could be a
                      "traditiona l" array, this could be an associative array, this could be
                      something like a deque. Today it can be one, tomorrow - another. At this
                      conceptual level there's no relation between container element count and
                      object size. The fact that this relation holds for a "traditiona l" array
                      is noting more than an accident, a low level detail, which has
                      absolutely no reason to play any role in the process of choosing the
                      index type.
                      [color=blue]
                      > In _The Standard C Library_, P. J. Plauger writes:
                      >
                      > "Unlike ptrdiff_t, however, size_t is /very/ useful. It is the safest type
                      > to represent any integer data object you use as an array subscript. You
                      > don't have to worry if a small array evolves into a very large one as the
                      > program changes. Subscript arithmetic will never overflow when performed in
                      > type size_t." and "You should make a point of using type size_t /anywhere/
                      > your program performs array subscripting or address arithmetic." (emphasis
                      > in original)[/color]

                      Great, but applies mostly to library-level (generic) code.

                      If in my program a have a dedicated typename for designating the day of
                      the week, say

                      typedef enum DayOfTheWeek { /* ... */ } DayOfTheWeek;

                      and in some place I need to iterate through an array indexed by the day
                      of the week, then I'd make a point of using 'DayOfTheWeek' to represent
                      the index, never the completely irrelevant 'size_t'.
                      [color=blue]
                      > The only reason one might prefer ptrdiff_t for array subscripts is where,
                      > due to looping, you need the ability to count down past zero. In this case,
                      > I would prefer ssize_t (where available) over ptrdiff_t, but first I'd
                      > consider whether it was feasible to restructure the loop condition such that
                      > a signed subscript wasn't needed.[/color]

                      I would do the latter.

                      --
                      Best regards,
                      Andrey Tarasevich

                      Comment

                      • Tor Rustad

                        #12
                        Re: type of array index?

                        "Andrey Tarasevich" <andreytarasevi ch@hotmail.com> wrote in message[color=blue]
                        > shmartonak@ticn et.com wrote:[color=green]
                        > > For maximum portability what should the type of an array index be?
                        > > Can any integer type be used safely? Or should I only use an
                        > > unsigned type? Or what?[/color][/color]

                        Any integer type is allowed. For example main() uses argc:

                        int main(int argc, char* argv[])

                        [color=blue][color=green]
                        > > If I'm using pointers to access array elements as *(mptr+k) where
                        > > I've declared[/color][/color]

                        [...]
                        [color=blue]
                        > However, from the pedantic point of view, 'size_t' is intended to
                        > implement a concept of "object size", while array index is more
                        > related to the concept of "container element count". These two
                        > concepts are not related and using 'size_t' for array indexing
                        > is a conceptual error.[/color]

                        Not correct, an array is an object and

                        sizeof array

                        return the size of that object. Hence, size_t is a good type choice
                        for an array index . Note that number of array elements

                        size_t N = sizeof (array) / sizeof (array[0]);

                        will never overflow with size_t.

                        --
                        Tor <torust AT online DOT no>


                        Comment

                        • Andrey Tarasevich

                          #13
                          Re: type of array index?

                          Tor Rustad wrote:[color=blue]
                          > ...[color=green]
                          >> However, from the pedantic point of view, 'size_t' is intended to
                          >> implement a concept of "object size", while array index is more
                          >> related to the concept of "container element count". These two
                          >> concepts are not related and using 'size_t' for array indexing
                          >> is a conceptual error.[/color]
                          >
                          > Not correct, an array is an object and
                          >
                          > sizeof array
                          >
                          > return the size of that object. Hence, size_t is a good type choice
                          > for an array index . Note that number of array elements
                          >
                          > size_t N = sizeof (array) / sizeof (array[0]);
                          >
                          > will never overflow with size_t.
                          > ...[/color]

                          And? This is exactly what I said in my message before the quoted part.
                          But how is this relevant within the context of paragraph quoted above?

                          Once again, the concept of "object size" is not related to the concept
                          of "container element count". The connection between the two for
                          built-in C arrays is purely parasitic. It is a mere coincidence, which
                          makes absolutely no difference at conceptual level.

                          --
                          Best regards,
                          Andrey Tarasevich

                          Comment

                          • Keith Thompson

                            #14
                            Re: type of array index?

                            Andrey Tarasevich <andreytarasevi ch@hotmail.com> writes:
                            [...][color=blue]
                            > Once again, the concept of "object size" is not related to the concept
                            > of "container element count". The connection between the two for
                            > built-in C arrays is purely parasitic. It is a mere coincidence, which
                            > makes absolutely no difference at conceptual level.[/color]

                            Object size and container element count are the same for character
                            arrays, and since an array element can't be smaller than one byte,
                            you're guaranteed that size_t is at least big enough to hold any array
                            index.

                            If you're writing code that deals with arrays generically (such as the
                            standard qsort() function), it's probably safest to use size_t. If
                            you're using something more specific to a given problem domain, and
                            you happen to know that an array will never have more than INT_MAX
                            elements, you can use int.

                            --
                            Keith Thompson (The_Other_Keit h) kst-u@mib.org <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.

                            Comment

                            • Stephen Sprunk

                              #15
                              Re: type of array index?


                              "Andrey Tarasevich" <andreytarasevi ch@hotmail.com> wrote in message
                              news:1148rhrldv e39b6@news.supe rnews.com...[color=blue]
                              > Stephen Sprunk wrote:[color=green][color=darkred]
                              > >> However, from the pedantic point of view, 'size_t' is intended to
                              > >> implement a concept of "object size", while array index is more
                              > >> related to the concept of "container element count". These two
                              > >> concepts are not related and using 'size_t' for array indexing is
                              > >> a conceptual error.[/color]
                              > >
                              > > Since an array is an object, and size_t is defined to be large
                              > > enough to represent the size of any object, size_t naturally
                              > > must be able to represent any possible array subscript.[/color]
                              >
                              > That's the very reason why I suggest using 'size_t' for array indexing
                              > in generic context. For example, in a generic array-support library.
                              >
                              > At application level there's rarely a need to have an array just for
                              > the sake of having an array.[/color]

                              Right, but if you get in the habit of writing code where the index is an
                              int, sooner or later you'll write code that (after it's been edited by a
                              dozen other coders) overflows that int but size_t would have worked.

                              Sure, size_t may be less efficient on some systems, but IMHO rarely enough
                              to offset the possibility of bugs in the future.
                              [color=blue][color=green]
                              > > In _The Standard C Library_, P. J. Plauger writes:
                              > >
                              > > "Unlike ptrdiff_t, however, size_t is /very/ useful. It is the
                              > > safest type to represent any integer data object you use as
                              > > an array subscript. You don't have to worry if a small array
                              > > evolves into a very large one as the program changes.
                              > > Subscript arithmetic will never overflow when performed in
                              > > type size_t." and "You should make a point of using type
                              > > size_t /anywhere/ your program performs array subscripting
                              > > or address arithmetic." (emphasis in original)[/color]
                              >
                              > Great, but applies mostly to library-level (generic) code.[/color]

                              IMHO, it applies to nearly all application code as well.
                              [color=blue]
                              > If in my program a have a dedicated typename for designating
                              > the day of the week, say
                              > ...[/color]

                              In that case, yes, I might declare the index as an int or even short, but
                              clear-cut cases like that are exceptions.

                              In most cases, the original coder has no idea what his code will eventually
                              evolve into, how other components of the same system will abuse it, or
                              whether the index will overflow ten years later and crash some
                              mission-critical system. Why take the chance unless you can prove it's
                              affecting performance?

                              S


                              Comment

                              Working...