Pointer to qualified poitner to qualified object

Discussion in 'C Programming' started by Szabolcs Borsanyi, May 30, 2008.

  1. Deal all,

    The type

    typedef double ***tmp_tensor3;

    is meant to represent a three-dimensional array. For some reasons the
    standard array-of-array-of-array will not work in my case.

    Can I convert an object of this type to the following type?

    typedef doule * const * const * tensor3;

    This would indicate that I would not like to mess up the indices, just
    modify the numbers.

    Suppose I have a variable of type tensor3, and a function is not meant to
    modify the numbers, so that would expect a const_testor3 object;

    typedef const doule * const * const * const_tensor3;

    But that also will not work without a cast.

    Is there a good way to express the meaning of a function that is not supposed
    to change the numbers inside of the tensor? Like putting all that in a struct
    or something more sophisticated?

    Szabolcs
    Szabolcs Borsanyi, May 30, 2008
    #1
    1. Advertising

  2. On Fri, May 30, 2008 at 03:13:09AM -0500, pete wrote:
    > Szabolcs Borsanyi wrote:
    >> Deal all,
    >>
    >> The type
    >>
    >> typedef double ***tmp_tensor3;
    >>
    >> is meant to represent a three-dimensional array. For some reasons the
    >> standard array-of-array-of-array will not work in my case.

    >
    > /* BEGIN new.c */
    >
    > #include <stdio.h>
    >
    > #define DIM_1 2
    > #define DIM_2 3
    > #define DIM_3 4
    >
    > typedef double tmp_tensor3[DIM_2][DIM_3];


    I am very sorry for wasting your time, but I think there is a misunderstanding.
    I do know how to use multidimensional arrays and also how to play with
    double ***-like representations. My question referred to the C standard's
    opinion about converting a (double ***) pointer to qualified versions.

    My statement that
    >> For some reasons the standard array-of-array-of-array will not work in
    >> my case.

    had not the meaning that I am struggled with it, but rather, I do know
    that double[][][] represents a different object than what I have in mind.
    In fact my three dimensional array have some identical elements.
    (3d lattice with periodic boundary conditions in the first two indices).

    So the question is still there: how to legally convert from (double***) to
    (double * const * const *) and then that to (double const * const * const *).
    I am worried about the compatibility of the types.

    Szabolcs
    Szabolcs Borsanyi, May 30, 2008
    #2
    1. Advertising

  3. Szabolcs Borsanyi

    Andrew Kerr Guest

    Szabolcs Borsanyi wrote:
    > So the question is still there: how to legally convert from (double***) to
    > (double * const * const *) and then that to (double const * const * const *).
    > I am worried about the compatibility of the types.


    Since you are casting from a non-constant pointer to a constant pointer,
    you can perform the cast safely. This applies to each layer of
    indirection. For example,

    typedef double * const * const * tensor3;
    typedef const double * const * const * const_tensor3;

    double ***ppp_tensor;
    tensor3 T = (tensor3)ppp_tensor;
    const_tensor3 cT = (const_tensor3)T;

    const int M, N, K; // dimensions of data cube
    int i, j, k; // variables of iteration
    for (i = 0; i < M; i++) {
    double * const * const row = T;
    for (j = 0; j < N; j++) {
    double * const col = row[j];
    for (k = 0; k < K; k++) {
    double el = col[k];
    }
    }
    }

    for (i = 0; i < M; i++) {
    const double * const * const row = cT;
    for (j = 0; j < N; j++) {
    const double * const col = row[j];
    for (k = 0; k < K; k++) {
    const double el = col[k];
    }
    }
    }

    I believe that satisfies your questions.

    --
    Andrew Kerr
    Andrew Kerr, May 30, 2008
    #3
  4. Szabolcs Borsanyi

    Flash Gordon Guest

    Andrew Kerr wrote, On 30/05/08 19:03:
    > Szabolcs Borsanyi wrote:
    >> So the question is still there: how to legally convert from
    >> (double***) to
    >> (double * const * const *) and then that to (double const * const *
    >> const *).
    >> I am worried about the compatibility of the types.

    >
    > Since you are casting from a non-constant pointer to a constant pointer,
    > you can perform the cast safely. This applies to each layer of
    > indirection. For example,


    <snip>

    There is a good discussion of the issues and the reason for the
    conversion not being explicit in question 11.10 of the comp.lang.c FAQ
    at http://c-faq.com/
    --
    Flash Gordon
    Flash Gordon, May 30, 2008
    #4
  5. Flash Gordon <> writes:
    > Andrew Kerr wrote, On 30/05/08 19:03:
    >> Szabolcs Borsanyi wrote:
    >>> So the question is still there: how to legally convert from
    >>> (double***) to
    >>> (double * const * const *) and then that to (double const * const *
    >>> const *).
    >>> I am worried about the compatibility of the types.

    >> Since you are casting from a non-constant pointer to a constant
    >> pointer, you can perform the cast safely. This applies to each layer
    >> of indirection. For example,

    >
    > <snip>
    >
    > There is a good discussion of the issues and the reason for the
    > conversion not being explicit in question 11.10 of the comp.lang.c FAQ
    > at http://c-faq.com/


    I think you mean "not being implicit".

    --
    Keith Thompson (The_Other_Keith) <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"
    Keith Thompson, May 30, 2008
    #5
  6. On Fri, 30 May 2008 07:31:54 UTC, Szabolcs Borsanyi
    <> wrote:

    > Deal all,
    >
    > The type
    >
    > typedef double ***tmp_tensor3;
    >
    > is meant to represent a three-dimensional array. For some reasons the
    > standard array-of-array-of-array will not work in my case.


    No, it means simply a pointer to a pointer to a pointer to a double.

    double a[2] is not a pointer but an array of 2 doubles
    double a[2][2] is an array of 2 arrrays of 2 doubles
    double a[2][2][2] means an array of an array of an array of 2 doubles.


    An array is not a pointer and a pointer is not an array.

    double *p is a pointer to a double or a ppointer to an array of
    unspezified size of doubles.

    double **p is a pointer to a pointer to a double or
    a pointer to a pointer to an array of unspezified size of type double
    or
    a pointer to an array of unspezified size of pointers to a double

    C is a bit lazy as it does not spezifies that a pointer points to a
    single object or an array of objects of that type.

    So again: a pointer is not an array.
    An array is not a pointer.
    The address of an array may decay to a pointer but it is not an array.

    --
    Tschau/Bye
    Herbert

    Visit http://www.ecomstation.de the home of german eComStation
    eComStation 1.2R Deutsch ist da!
    Herbert Rosenau, Jun 2, 2008
    #6
  7. "Herbert Rosenau" <> writes:
    [...]
    > C is a bit lazy as it does not spezifies that a pointer points to a
    > single object or an array of objects of that type.

    [...]

    Incorrect. A pointer to a single object, such as
    int *ptr1;
    and a pointer to an array, such as:
    int (*ptr2)[2];
    are of two distinct types.

    The valid point I suspect you were making is that an array is
    typically accessed via a pointer to its first element, with pointer
    arithmetic leting you step through the elements of the array.
    Pointers to arrays actually aren't used very often (except implicitly
    in operations on declared multi-dimensional arrays).

    --
    Keith Thompson (The_Other_Keith) <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"
    Keith Thompson, Jun 2, 2008
    #7
  8. On Mon, 2 Jun 2008 20:35:24 UTC, Keith Thompson <> wrote:

    > "Herbert Rosenau" <> writes:
    > [...]
    > > C is a bit lazy as it does not spezifies that a pointer points to a
    > > single object or an array of objects of that type.

    > [...]
    >
    > Incorrect. A pointer to a single object, such as
    > int *ptr1;
    > and a pointer to an array, such as:
    > int (*ptr2)[2];
    > are of two distinct types.
    >
    > The valid point I suspect you were making is that an array is
    > typically accessed via a pointer to its first element, with pointer
    > arithmetic leting you step through the elements of the array.
    > Pointers to arrays actually aren't used very often (except implicitly
    > in operations on declared multi-dimensional arrays).
    >

    Really? In my programs I make heavy use of arrays to define define
    data - but use only pointers to access the data therein.

    The usage of multidimensional arrays is in contrast to that really
    rare.

    --
    Tschau/Bye
    Herbert

    Visit http://www.ecomstation.de the home of german eComStation
    eComStation 1.2R Deutsch ist da!
    Herbert Rosenau, Jun 4, 2008
    #8
  9. "Herbert Rosenau" <> writes:
    > On Mon, 2 Jun 2008 20:35:24 UTC, Keith Thompson <> wrote:
    >> "Herbert Rosenau" <> writes:
    >> [...]
    >> > C is a bit lazy as it does not spezifies that a pointer points to a
    >> > single object or an array of objects of that type.

    >> [...]
    >>
    >> Incorrect. A pointer to a single object, such as
    >> int *ptr1;
    >> and a pointer to an array, such as:
    >> int (*ptr2)[2];
    >> are of two distinct types.
    >>
    >> The valid point I suspect you were making is that an array is
    >> typically accessed via a pointer to its first element, with pointer
    >> arithmetic leting you step through the elements of the array.
    >> Pointers to arrays actually aren't used very often (except implicitly
    >> in operations on declared multi-dimensional arrays).
    >>

    > Really?


    Yes. I may not have stated it as clearly as I'd like. Actual
    multidimensional arrays (i.e., arrays of arrays) are probably fairly
    rare, but I suspect they're the most common context in which pointers
    to arrays are used.

    > In my programs I make heavy use of arrays to define define
    > data - but use only pointers to access the data therein.


    Right, but presumably you use a pointer to the array's *element type*,
    not to the array.

    > The usage of multidimensional arrays is in contrast to that really
    > rare.


    Agreed.

    --
    Keith Thompson (The_Other_Keith) <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"
    Keith Thompson, Jun 4, 2008
    #9
  10. Szabolcs Borsanyi

    Old Wolf Guest

    On May 30, 7:31 pm, Szabolcs Borsanyi <> wrote:
    >
    > typedef double ***tmp_tensor3;
    >
    > Can I convert an object of this type to the following type?
    >
    > typedef doule * const * const * tensor3;


    Yes, but you must use a cast. (IMHO this is
    a defect in the language - other C-like
    languages allow the conversion without a cast).
    Old Wolf, Jun 5, 2008
    #10
  11. On Wed, 4 Jun 2008 21:00:02 UTC, Keith Thompson <> wrote:

    > "Herbert Rosenau" <> writes:
    > > On Mon, 2 Jun 2008 20:35:24 UTC, Keith Thompson <> wrote:
    > >> "Herbert Rosenau" <> writes:
    > >> [...]
    > >> > C is a bit lazy as it does not spezifies that a pointer points to a
    > >> > single object or an array of objects of that type.
    > >> [...]
    > >>
    > >> Incorrect. A pointer to a single object, such as
    > >> int *ptr1;
    > >> and a pointer to an array, such as:
    > >> int (*ptr2)[2];
    > >> are of two distinct types.
    > >>
    > >> The valid point I suspect you were making is that an array is
    > >> typically accessed via a pointer to its first element, with pointer
    > >> arithmetic leting you step through the elements of the array.
    > >> Pointers to arrays actually aren't used very often (except implicitly
    > >> in operations on declared multi-dimensional arrays).
    > >>

    > > Really?

    >
    > Yes. I may not have stated it as clearly as I'd like. Actual
    > multidimensional arrays (i.e., arrays of arrays) are probably fairly
    > rare, but I suspect they're the most common context in which pointers
    > to arrays are used.
    >
    > > In my programs I make heavy use of arrays to define define
    > > data - but use only pointers to access the data therein.

    >
    > Right, but presumably you use a pointer to the array's *element type*,
    > not to the array.


    No, yes. I use the array at whole (to be exact its name) as actual
    parameter to fuctions who may select one, much or all members of the
    array to call other fuctions to do some work with the given array
    members using the fact that the name of an array is interpreted by C
    as anything of 'the array as whole' and the address of the first
    element.

    Anyway I use plain arrays seldom because I love it to build structures
    to collect data that goes together to hold and handle together. So I
    have a high limited number of arrays but a high number of pointers to
    them but only a limited number to pointers to single members of
    members of arrays. As a single member of an array can point to other
    arrays but releative seldom to a single member of an array.

    --
    Tschau/Bye
    Herbert

    Visit http://www.ecomstation.de the home of german eComStation
    eComStation 1.2R Deutsch ist da!
    Herbert Rosenau, Jun 5, 2008
    #11
  12. "Herbert Rosenau" <> writes:
    > On Wed, 4 Jun 2008 21:00:02 UTC, Keith Thompson <> wrote:
    >> "Herbert Rosenau" <> writes:
    >> > On Mon, 2 Jun 2008 20:35:24 UTC, Keith Thompson <> wrote:
    >> >> "Herbert Rosenau" <> writes:
    >> >> [...]
    >> >> > C is a bit lazy as it does not spezifies that a pointer points to a
    >> >> > single object or an array of objects of that type.
    >> >> [...]
    >> >>
    >> >> Incorrect. A pointer to a single object, such as
    >> >> int *ptr1;
    >> >> and a pointer to an array, such as:
    >> >> int (*ptr2)[2];
    >> >> are of two distinct types.
    >> >>
    >> >> The valid point I suspect you were making is that an array is
    >> >> typically accessed via a pointer to its first element, with pointer
    >> >> arithmetic leting you step through the elements of the array.
    >> >> Pointers to arrays actually aren't used very often (except implicitly
    >> >> in operations on declared multi-dimensional arrays).
    >> >>
    >> > Really?

    >>
    >> Yes. I may not have stated it as clearly as I'd like. Actual
    >> multidimensional arrays (i.e., arrays of arrays) are probably fairly
    >> rare, but I suspect they're the most common context in which pointers
    >> to arrays are used.
    >>
    >> > In my programs I make heavy use of arrays to define define
    >> > data - but use only pointers to access the data therein.

    >>
    >> Right, but presumably you use a pointer to the array's *element type*,
    >> not to the array.

    >
    > No, yes.


    What?

    > I use the array at whole (to be exact its name) as actual
    > parameter to fuctions who may select one, much or all members of the
    > array to call other fuctions to do some work with the given array
    > members using the fact that the name of an array is interpreted by C
    > as anything of 'the array as whole' and the address of the first
    > element.


    Ok, then you're passing a pointer to the first element of the array,
    and using that pointer inside the function to access that and other
    elements of the array.

    For example:

    void func(int *param);
    ...
    int arr[10];
    func(arr);

    The value you're passing to func is of type ``int*'' (pointer to int),
    not of type ``int(*)[10]'' (pointer to array 10 of int).

    > Anyway I use plain arrays seldom because I love it to build structures
    > to collect data that goes together to hold and handle together. So I
    > have a high limited number of arrays but a high number of pointers to
    > them but only a limited number to pointers to single members of
    > members of arrays. As a single member of an array can point to other
    > arrays but releative seldom to a single member of an array.


    Are you *really* using pointers to arrays, or are you (perhaps
    implicitly) just using pointers to array elements? If the former, can
    you show an example?

    --
    Keith Thompson (The_Other_Keith) <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"
    Keith Thompson, Jun 5, 2008
    #12
  13. On Thu, 5 Jun 2008 21:22:52 UTC, Keith Thompson <> wrote:

    > "Herbert Rosenau" <> writes:
    > > On Wed, 4 Jun 2008 21:00:02 UTC, Keith Thompson <> wrote:
    > >> "Herbert Rosenau" <> writes:
    > >> > On Mon, 2 Jun 2008 20:35:24 UTC, Keith Thompson <> wrote:
    > >> >> "Herbert Rosenau" <> writes:
    > >> >> [...]
    > >> >> > C is a bit lazy as it does not spezifies that a pointer points to a
    > >> >> > single object or an array of objects of that type.
    > >> >> [...]
    > >> >>
    > >> >> Incorrect. A pointer to a single object, such as
    > >> >> int *ptr1;
    > >> >> and a pointer to an array, such as:
    > >> >> int (*ptr2)[2];
    > >> >> are of two distinct types.
    > >> >>
    > >> >> The valid point I suspect you were making is that an array is
    > >> >> typically accessed via a pointer to its first element, with pointer
    > >> >> arithmetic leting you step through the elements of the array.
    > >> >> Pointers to arrays actually aren't used very often (except implicitly
    > >> >> in operations on declared multi-dimensional arrays).
    > >> >>
    > >> > Really?
    > >>
    > >> Yes. I may not have stated it as clearly as I'd like. Actual
    > >> multidimensional arrays (i.e., arrays of arrays) are probably fairly
    > >> rare, but I suspect they're the most common context in which pointers
    > >> to arrays are used.
    > >>
    > >> > In my programs I make heavy use of arrays to define define
    > >> > data - but use only pointers to access the data therein.
    > >>
    > >> Right, but presumably you use a pointer to the array's *element type*,
    > >> not to the array.

    > >
    > > No, yes.

    >
    > What?
    >
    > > I use the array at whole (to be exact its name) as actual
    > > parameter to fuctions who may select one, much or all members of the
    > > array to call other fuctions to do some work with the given array
    > > members using the fact that the name of an array is interpreted by C
    > > as anything of 'the array as whole' and the address of the first
    > > element.

    >
    > Ok, then you're passing a pointer to the first element of the array,
    > and using that pointer inside the function to access that and other
    > elements of the array.
    >
    > For example:
    >
    > void func(int *param);
    > ...
    > int arr[10];
    > func(arr);
    >
    > The value you're passing to func is of type ``int*'' (pointer to int),
    > not of type ``int(*)[10]'' (pointer to array 10 of int).
    >
    > > Anyway I use plain arrays seldom because I love it to build structures
    > > to collect data that goes together to hold and handle together. So I
    > > have a high limited number of arrays but a high number of pointers to
    > > them but only a limited number to pointers to single members of
    > > members of arrays. As a single member of an array can point to other
    > > arrays but releative seldom to a single member of an array.

    >
    > Are you *really* using pointers to arrays, or are you (perhaps
    > implicitly) just using pointers to array elements? If the former, can
    > you show an example?
    >


    struct X *f(struct X *p);

    Please tell me what f() gets and what if gives back;

    You can't distinguish between

    f gets called with a pointer to a single struct
    f gets called with an array of structs with an unknown number of
    elements

    And you can't distinguish too what f() returns. Returns it a pointer
    to a single struct or a pointer to an array of structs?

    In C89 you don't have VLA, so you can't not even give a hint other
    than in docomuntation or reading the source of f() carefully.

    --
    Tschau/Bye
    Herbert

    Visit http://www.ecomstation.de the home of german eComStation
    eComStation 1.2R Deutsch ist da!
    Herbert Rosenau, Jun 8, 2008
    #13
  14. "Herbert Rosenau" <> writes:
    [...]
    > struct X *f(struct X *p);
    >
    > Please tell me what f() gets and what if gives back;


    It gets a pointer to struct X. It gives back a pointer to struct X.

    > You can't distinguish between
    >
    > f gets called with a pointer to a single struct
    > f gets called with an array of structs with an unknown number of
    > elements


    Strictly speaking, the former is possible in C, and the latter is not.
    You cannot directly pass an array as a function argument.

    More loosely, you're right, of course. Given just the declaration
    you've shown us, there's no way to tell whether the argument passed to
    f was a pointer to a single struct or a pointer to the first element
    of an array of structs.

    If it's intended that the argument is going to be a pointer to an
    array, then the function should have some mechanism for the caller to
    tell it how many elements the array has. The language doesn't provide
    a good way to tightly associate this information with the pointer
    declaration, so it's generally done via program logic:

    struct X *f(struct X *p, size_t len);

    > And you can't distinguish too what f() returns. Returns it a pointer
    > to a single struct or a pointer to an array of structs?


    It returns a pointer to a struct. It does not return a pointer to an
    array. If it did, its declaration would be quite different. If I'm not
    mistaken, it would be something like this:

    struct X (*f(int (*p)[LEN]))[LEN]

    where LEN needs to be a constant expression. Note that I've changed
    both the argument type and the return type. Judicious use of typedefs
    might make this more legible.

    C actually does have pointers to arrays. However, pointers to arrays
    are rarely used to manipulate arrays (other than implicitly in
    multidimensional array, which are themselves relatively rare).
    Instead, arrays are usually manipulated via a pointer to the first
    element of the array *which is of a distinct type*.

    > In C89 you don't have VLA, so you can't not even give a hint other
    > than in docomuntation or reading the source of f() carefully.


    Right.

    Note that I didn't quote any of my previous article, the one to which
    you were replying. This is because, as far as I can tell, you didn't
    actually dispute or otherwise address anything I wrote there.

    I invite you to go back and do so. If I've gotten something wrong,
    I'd love to hear about it.

    --
    Keith Thompson (The_Other_Keith) <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"
    Keith Thompson, Jun 8, 2008
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Alexander Grigoriev
    Replies:
    0
    Views:
    384
    Alexander Grigoriev
    Sep 12, 2003
  2. Replies:
    10
    Views:
    693
    Chris Torek
    Feb 4, 2005
  3. jimjim
    Replies:
    16
    Views:
    835
    Jordan Abel
    Mar 28, 2006
  4. gibby
    Replies:
    6
    Views:
    280
    Kaz Kylheku
    Apr 18, 2009
  5. Nathan Rice
    Replies:
    0
    Views:
    169
    Nathan Rice
    Dec 15, 2011
Loading...

Share This Page