passing int * * to function as const

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • John D. Goulden

    passing int * * to function as const

    Hopefully this question will make sense; if not, please correct my thinking
    :)

    If I wish to create a one-dimensional array at run time, I write

    int * myArray = new int [size];

    and pass that array to functions using prototypes

    void foo1 ( int * );

    or as

    void foo2 (const int *);

    depending on whether or not I wish the function to be able to modify the
    data in the array.
    Both of these seem to work just fine.

    Now I wish to do the same with int * *. I create the 'table' as

    int * * myTable = new int * [rows];
    for(int i = 0; i < rows; ++i)
    myTable[i] = new int [cols];

    and send it to functions with prototypes

    void bar1 ( int * *);

    or

    void bar2 ( const int * *);

    Everything works great except that last line: the compilers complain about
    "cannot convert from int * * to const int * *; conversion loses qualifiers"
    or something to that effect.

    How can I send this int * * 'table' to a function in such a way that the
    function can't modify the data - that is, send it as const, as I can do with
    an int * 'array' ?

    Using std::vector instead doesn't answer my question, so please don't
    suggest it.

    --
    John Goulden
    jgoulden@okcu.e du




    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.m oderated. First time posters: Do this! ]
  • Artie Gold

    #2
    Re: passing int * * to function as const

    John D. Goulden wrote:[color=blue]
    > Hopefully this question will make sense; if not, please correct my thinking
    > :)
    >
    > If I wish to create a one-dimensional array at run time, I write
    >
    > int * myArray = new int [size];
    >
    > and pass that array to functions using prototypes
    >
    > void foo1 ( int * );
    >
    > or as
    >
    > void foo2 (const int *);
    >
    > depending on whether or not I wish the function to be able to modify the
    > data in the array.
    > Both of these seem to work just fine.
    >
    > Now I wish to do the same with int * *. I create the 'table' as
    >
    > int * * myTable = new int * [rows];
    > for(int i = 0; i < rows; ++i)
    > myTable[i] = new int [cols];
    >
    > and send it to functions with prototypes
    >
    > void bar1 ( int * *);
    >
    > or
    >
    > void bar2 ( const int * *);
    >
    > Everything works great except that last line: the compilers complain about
    > "cannot convert from int * * to const int * *; conversion loses qualifiers"
    > or something to that effect.
    >
    > How can I send this int * * 'table' to a function in such a way that the
    > function can't modify the data - that is, send it as const, as I can do with
    > an int * 'array' ?[/color]

    Please see:



    (you *did* read the FAQ first, didn't you?)
    [color=blue]
    >
    > Using std::vector instead doesn't answer my question, so please don't
    > suggest it.
    >[/color]

    HTH,
    --ag

    --
    Artie Gold -- Austin, Texas
    Oh, for the good old days of regular old SPAM.

    Comment

    • Andrew Koenig

      #3
      Re: passing int * * to function as const


      "John D. Goulden" <jgoulden_news@ goulden.org> wrote in message
      news:bnmv5d02a0 4@enews2.newsgu y.com...
      [color=blue]
      > Now I wish to do the same with int * *. I create the 'table' as[/color]
      [color=blue]
      > int * * myTable = new int * [rows];
      > for(int i = 0; i < rows; ++i)
      > myTable[i] = new int [cols];[/color]
      [color=blue]
      > and send it to functions with prototypes[/color]
      [color=blue]
      > void bar1 ( int * *);[/color]
      [color=blue]
      > or[/color]
      [color=blue]
      > void bar2 ( const int * *);[/color]
      [color=blue]
      > Everything works great except that last line: the compilers complain about
      > "cannot convert from int * * to const int * *; conversion loses[/color]
      qualifiers"[color=blue]
      > or something to that effect.[/color]
      [color=blue]
      > How can I send this int * * 'table' to a function in such a way that the
      > function can't modify the data - that is, send it as const, as I can do[/color]
      with[color=blue]
      > an int * 'array' ?[/color]

      Define bar2 as

      void bar2 (const int *const *);

      In general, there is no conversion from T** to const T**, because to do
      otherwise would open a hole in the type system. I am sure that others will
      explain in more detail, and I feel lazy today, so I'll leave it to them.


      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.m oderated. First time posters: Do this! ]

      Comment

      • Alexander Stippler

        #4
        Re: passing int * * to function as const

        John D. Goulden wrote:
        [color=blue]
        > Hopefully this question will make sense; if not, please correct my
        > thinking
        > :)
        >
        > If I wish to create a one-dimensional array at run time, I write
        >
        > int * myArray = new int [size];
        >
        > and pass that array to functions using prototypes
        >
        > void foo1 ( int * );
        >
        > or as
        >
        > void foo2 (const int *);
        >
        > depending on whether or not I wish the function to be able to modify the
        > data in the array.
        > Both of these seem to work just fine.
        >
        > Now I wish to do the same with int * *. I create the 'table' as
        >
        > int * * myTable = new int * [rows];
        > for(int i = 0; i < rows; ++i)
        > myTable[i] = new int [cols];
        >
        > and send it to functions with prototypes
        >
        > void bar1 ( int * *);
        >
        > or
        >
        > void bar2 ( const int * *);
        >
        > Everything works great except that last line: the compilers complain about
        > "cannot convert from int * * to const int * *; conversion loses
        > qualifiers" or something to that effect.
        >
        > How can I send this int * * 'table' to a function in such a way that the
        > function can't modify the data - that is, send it as const, as I can do
        > with an int * 'array' ?
        >
        > Using std::vector instead doesn't answer my question, so please don't
        > suggest it.
        >[/color]

        just use
        const int * const *
        to make the intermediate pointer point to const, too.

        alex.

        [ See http://www.gotw.ca/resources/clcm.htm for info about ]
        [ comp.lang.c++.m oderated. First time posters: Do this! ]

        Comment

        • Andrey Tarasevich

          #5
          Re: passing int * * to function as const

          John D. Goulden wrote:[color=blue]
          > ...
          > Now I wish to do the same with int * *. I create the 'table' as
          >
          > int * * myTable = new int * [rows];
          > for(int i = 0; i < rows; ++i)
          > myTable[i] = new int [cols];
          >
          > and send it to functions with prototypes
          >
          > void bar1 ( int * *);
          >
          > or
          >
          > void bar2 ( const int * *);
          >
          > Everything works great except that last line: the compilers complain about
          > "cannot convert from int * * to const int * *; conversion loses qualifiers"
          > or something to that effect.
          >
          > How can I send this int * * 'table' to a function in such a way that the
          > function can't modify the data - that is, send it as const, as I can do with
          > an int * 'array' ?
          > ...[/color]

          Values of type 'int**' are not convertible to type 'const int**', as you
          can read in the FAQ (see Artie's reply). However, in C++ they are
          convertible to type 'const int* const*'. I can't be sure what you need
          in your case, but in many similar situations 'const int* const*' is even
          more appropriate than 'const int**'. Maybe you should consider declaring
          'bar2' as

          void bar2(const int * const*);

          --
          Best regards,
          Andrey Tarasevich
          Brainbench C and C++ Programming MVP


          [ See http://www.gotw.ca/resources/clcm.htm for info about ]
          [ comp.lang.c++.m oderated. First time posters: Do this! ]

          Comment

          • Paul Kunysch

            #6
            Re: passing int * * to function as const

            > How can I send this int * * 'table' to a function in such a way that the[color=blue]
            > function can't modify the data - that is, send it as const, as I can do with
            > an int * 'array' ?[/color]

            Make the pointers const first ... :

            void foo1(const int * const * arg);
            void foo2(int * const * arg);

            int bar(int argc, char *argv[]) {
            int size = 5;
            int ** arr = new int * [size];
            for (int i=0; i<size; ++i)
            arr[i] = new int(i);
            foo1(arr);
            foo2(arr);
            }

            This compiles as expected but I'd appreciate a good explanation why the
            "const int **" argument doesn't work. :-}

            - Paul


            [ See http://www.gotw.ca/resources/clcm.htm for info about ]
            [ comp.lang.c++.m oderated. First time posters: Do this! ]

            Comment

            • Ben Hutchings

              #7
              Re: passing int * * to function as const

              John D. Goulden wrote:
              <snip>[color=blue]
              > Now I wish to do the same with int * *. I create the 'table' as
              >
              > int * * myTable = new int * [rows];
              > for(int i = 0; i < rows; ++i)
              > myTable[i] = new int [cols];
              >
              > and send it to functions with prototypes
              >
              > void bar1 ( int * *);
              >
              > or
              >
              > void bar2 ( const int * *);
              >
              > Everything works great except that last line: the compilers
              > complain about "cannot convert from int * * to const int * *;
              > conversion loses qualifiers" or something to that effect.[/color]

              If the conversion was allowed, you wouldn't get any error
              messages about this code:

              int i;
              const int ci;
              int * pi = &i;
              int ** ppi = &pi;
              const int ** ppci = ppi; // error, but suppose it isn't
              *ppci = ci; // modifies pi
              *pi = 0; // attempts to modify ci - undefined behaviour
              [color=blue]
              > How can I send this int * * 'table' to a function in such a
              > way that the function can't modify the data - that is, send
              > it as const, as I can do with an int * 'array' ?[/color]
              <snip>

              The type of bar2's parameter should be const int * const *.
              Conversion to this type is allowed because you can't use it
              to modify the intermediate pointers.

              [ See http://www.gotw.ca/resources/clcm.htm for info about ]
              [ comp.lang.c++.m oderated. First time posters: Do this! ]

              Comment

              • Antonio

                #8
                Re: passing int * * to function as const

                > void bar2 ( const int * *);

                static_cast<con st int **>(yourptrptrt oint);


                [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                [ comp.lang.c++.m oderated. First time posters: Do this! ]

                Comment

                • Micah Cowan

                  #9
                  Re: passing int * * to function as const

                  "John D. Goulden" <jgoulden_news@ goulden.org> writes:

                  <snip>
                  [color=blue]
                  > Now I wish to do the same with int * *. I create the 'table' as
                  >
                  > int * * myTable = new int * [rows];
                  > for(int i = 0; i < rows; ++i)
                  > myTable[i] = new int [cols];
                  >
                  > and send it to functions with prototypes
                  >
                  > void bar1 ( int * *);
                  >
                  > or
                  >
                  > void bar2 ( const int * *);
                  >
                  > Everything works great except that last line: the compilers complain about
                  > "cannot convert from int * * to const int * *; conversion loses qualifiers"
                  > or something to that effect.[/color]

                  This is a FAQ.



                  The solution is to change bar2()'s prototype to:

                  void bar2 ( const int * const * );

                  --
                  Micah J. Cowan
                  micah@cowan.nam e

                  [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                  [ comp.lang.c++.m oderated. First time posters: Do this! ]

                  Comment

                  • John Potter

                    #10
                    Re: passing int * * to function as const

                    On 29 Oct 2003 11:43:11 -0500, "John D. Goulden"
                    <jgoulden_news@ goulden.org> wrote:
                    [color=blue]
                    > Now I wish to do the same with int * *. I create the 'table' as[/color]
                    [color=blue]
                    > int * * myTable = new int * [rows];
                    > for(int i = 0; i < rows; ++i)
                    > myTable[i] = new int [cols];[/color]
                    [color=blue]
                    > and send it to functions with prototypes[/color]
                    [color=blue]
                    > void bar1 ( int * *);[/color]

                    Do you mind if bar1 changes some row to contain a different
                    number of elements? If you do, you should prevent it from
                    doing that to you by declaring it as

                    void bar1 ( int * const *);

                    Now it can change the ints but not the number of them.
                    [color=blue]
                    > or[/color]
                    [color=blue]
                    > void bar2 ( const int * *);[/color]

                    Likewise here.

                    void bar2 ( int const * const *);

                    And everything works. See the comp.std.c++ faq for why you can
                    not send an int** to an int const** without a cast. It is unsafe
                    and was just covered a day or two ago here.

                    In the above, the left most const can go befor or after the int,
                    but the others always come after. Some of us never put one on
                    the left to avoid that special case.

                    John

                    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                    [ comp.lang.c++.m oderated. First time posters: Do this! ]

                    Comment

                    • Siemel Naran

                      #11
                      Re: passing int * * to function as const

                      "John D. Goulden" <jgoulden_news@ goulden.org> wrote in message
                      [color=blue]
                      > void bar1 ( int * *);
                      > void bar2 ( const int * *);[/color]
                      [color=blue]
                      > Everything works great except that last line: the compilers complain about
                      > "cannot convert from int * * to const int * *; conversion loses[/color]
                      qualifiers"[color=blue]
                      > or something to that effect.[/color]

                      See the concurrent thread "Error C2440 when allocating array of pointers"
                      for an explanation why the direct conversion from int * * to int const * *
                      is an error.

                      --
                      +++++++++++
                      Siemel Naran


                      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                      [ comp.lang.c++.m oderated. First time posters: Do this! ]

                      Comment

                      • Siemel Naran

                        #12
                        Re: passing int * * to function as const

                        "Antonio" <a[NULL]mazzeo@email[DOT].it> wrote in message news:2iSnb.7548 7
                        [color=blue][color=green]
                        > > void bar2 ( const int * *);[/color]
                        >
                        > static_cast<con st int **>(yourptrptrt oint);[/color]

                        Is static_cast or const_cast the correct cast to use? I always thought it
                        was const_cast, but I could be wrong.

                        --
                        +++++++++++
                        Siemel Naran


                        [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                        [ comp.lang.c++.m oderated. First time posters: Do this! ]

                        Comment

                        Working...