cast multi-dimension array to pointer: T[][] to T*

Discussion in 'C Programming' started by lovecreatesbea...@gmail.com, Apr 26, 2008.

  1. Guest

    Is it always legal to cast expressions of type of multi-dimension
    array to type of pointer?
    Including:
    T[] to T* ,
    T[][] to T* ,
    T[][][] to T* ,
    and so on...

    For example:
    int *mtxrot1d(int *p, int n);
    int a2[N][N];
    int a3[N][N][N];

    mtxrot1d((int*)a2);
    mtxrot1d((int*)a3);

    Thank you for your time.
    , Apr 26, 2008
    #1
    1. Advertising

  2. Guest

    On Apr 26, 12:26 pm, ""
    <> wrote:
    > Is it always legal to cast expressions of type of multi-dimension
    > array to type of pointer?
    > Including:
    > T[] to T* ,
    > T[][] to T* ,
    > T[][][] to T* ,
    > and so on...
    >
    > For example:
    > int *mtxrot1d(int *p, int n);
    > int a2[N][N];
    > int a3[N][N][N];
    >
    > mtxrot1d((int*)a2);
    > mtxrot1d((int*)a3);
    >
    > Thank you for your time.


    Of course not.
    It's a terrible lie to say that (int *) is equal to (int [N][N]). At
    most, (int [N][N]) could be equal to (int (*)[N])
    , Apr 26, 2008
    #2
    1. Advertising

  3. Guest

    On Apr 26, 5:26 pm, ""
    <> wrote:
    >     mtxrot1d((int*)a2);
    >     mtxrot1d((int*)a3);


    sorry for the missed arguments:
    mtxrot1d((int*)a2, i);
    mtxrot1d((int*)a3, i);
    , Apr 26, 2008
    #3
  4. Guest

    On Apr 26, 5:34 pm, wrote:
    > On Apr 26, 12:26 pm, ""
    > >     int *mtxrot1d(int *p, int n);
    > >     int a2[N][N];
    > >     int a3[N][N][N];
    > >     mtxrot1d((int*)a2);
    > >     mtxrot1d((int*)a3);


    > It's a terrible lie to say that (int *) is equal to (int [N][N]). At
    > most, (int [N][N]) could be equal to (int (*)[N])- Hide quoted text -


    K&R2 says multiple dimension array is kind of singly dimensional
    array. For example these arrays: a1, and a2.

    int a1[6] = {1, 2, 3, 4, 5, 6};
    int a2[2][3] = {{1, 2, 3}, {4, 5, 6}};
    int *p;

    +-+-+-+-+-+-+
    a1: |1|2|3|4|5|6|
    +-+-+-+-+-+-+

    +-+-+-+ +-+-+-+
    a2: |1|2|3| |4|5|6|
    +-+-+-+ +-+-+-+

    Their element type also are the same. We can do this address
    arithmetic on singly dimension array a1:
    p = (int*)a1;
    p++;

    Are we not guaranteed to do this address arithmetic on multiple
    dimension array a2?
    p = (int*)a2;
    p++;
    , Apr 26, 2008
    #4
  5. On Sat, 26 Apr 2008 02:26:34 -0700 (PDT),
    "" <> wrote:

    >Is it always legal to cast expressions of type of multi-dimension
    >array to type of pointer?
    >Including:
    > T[] to T* ,
    > T[][] to T* ,
    > T[][][] to T* ,
    > and so on...
    >
    >For example:
    > int *mtxrot1d(int *p, int n);
    > int a2[N][N];
    > int a3[N][N][N];
    >
    > mtxrot1d((int*)a2);



    Typos in the function calls corrected in OP's subsequent post.

    > mtxrot1d((int*)a3);


    From a syntax point of view, yes. Ignoring the three exceptions you
    should know by now, an expression with type "array of ..." is
    converted to the address of the first element of the array with type
    pointer to element type. Therefore
    ptr = (cast)array;
    is identical to
    ptr = (cast)(&array[0]);
    and you are allowed to cast an object pointer to a different type of
    object pointer.

    Whether the result of the operation is well defined is a different
    question. However, in this case, the answer will always be yes.
    Regardless of the number of dimensions in the array, the array name is
    converted to the starting address of the array. This address is just
    the address of the first byte occupied by the array. What the number
    of dimensions does affect is the type of this value. Using your
    examples, the expression a2 has type int(*)[N] and the expression a3
    has type int(*)[N][N]. What the cast does is remove this "dimension
    dependence" by converting both expressions to type int* without
    changing the address itself.

    In all cases, this is guaranteed to produce a pointer to the first
    "basic element" of the array. This is because the array a3 and its
    first element a3[0] start at the same address and this relationship is
    recursive. So the array a3[0] and its first element a3[0][0] start at
    the same address and the same for a3[0][0] and a3[0][0][0].
    a3[0][0][0] is the fundamental element.

    Please note that I have only addressed the initial value of the
    conversion. Whether or not you can use the resulting pointer to step
    through all the array elements created a heated discussion a few years
    ago. Issues raised included bounds checking, fragmented memory
    architectures, the DS6000 (not to be confused with the IBM disk
    storage system named DS6800), language lawyering (regarding the
    standard itself), etc. Given the current signal to noise ratio, I
    hope this doesn't revitalize that topic.


    Remove del for email
    Barry Schwarz, Apr 26, 2008
    #5
  6. Chris Torek Guest

    In article <>
    <> wrote:
    >Is it always legal to cast expressions of type of multi-dimension
    >array to type of pointer?
    >Including:
    > T[] to T* ,
    > T[][] to T* ,
    > T[][][] to T* ,
    > and so on...


    It is certainly syntactically valid. It is a somewhat dodgy thing
    to do, though.

    Given an actual array object, even if it is an array whose elements
    are in turn arrays, you can always compute the "value" of the
    (outermost, in this case) array. That is:

    T arr[M][N];

    arr;

    computes the address of the first element of arr, i.e., &arr[0].
    In this case, this value has type "T (*)[N]", i.e., "pointer to
    array N of T". (If "arr;" is the entire statement, this computes
    the value, then discards it.)

    If we have an array of arrays of arrays:

    T arr2[Z][M][N];

    then &arr2[0] has type "pointer to array M of array N of T", or
    "T (*)[M][N]".

    It is even (I claim) "semantically valid", at least in a dodgy
    fashion, since (I claim) the address of the first element of the
    array-of-arrays is always "alignment compatible" with the address
    of the first element of the "innermost" array. In particular, see
    <http://web.torek.net/torek/c/pa.html>, and consider that the
    alignment requirements of each circle (or ellipse) are "the same",
    as they are solely determined by the "innermost" element type
    (the type named "T" in the original poster's question).

    However, the folks who interpret the various C Standards (C89 and
    C99) tell us that using this "innermost element" pointer to access
    the entire array contents is not guaranteed to work. I think C
    would be a better language if it *were* guaranteed to work, and
    in practice it seems to work on all existing implementations,
    but it may be wise to avoid depending on it, "just in case".

    Even if it does always work, the "dodginess" is emphasized by the
    need for careful "programmer-level work" to understand, maintain,
    and correctly manage all the "stride" information (as it is called
    in compiler circles) needed to access each array element. (Again,
    see the web page above.) C99's Variable Length Arrays provide a
    convenient "compiler-managed" method of working with the necessary
    stride information, so that the programmer does not have to do all
    the grunt work. If C made the guarantees that I wish it did, you
    could do this (manually) in C89, instead of relying on the C99
    compiler's VLAs, but it is probably better to use the C99 feature.
    (Of course, this assumes your C compiler supports it.)
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: gmail (figure it out) http://web.torek.net/torek/index.html
    Chris Torek, Apr 26, 2008
    #6
  7. "" <> writes:
    > Is it always legal to cast expressions of type of multi-dimension
    > array to type of pointer?
    > Including:
    > T[] to T* ,
    > T[][] to T* ,
    > T[][][] to T* ,
    > and so on...
    >
    > For example:
    > int *mtxrot1d(int *p, int n);
    > int a2[N][N];
    > int a3[N][N][N];
    >
    > mtxrot1d((int*)a2);
    > mtxrot1d((int*)a3);
    >
    > Thank you for your time.


    Others have discussed the potential dangers of doing the conversion.
    I'll just mention that you don't need to use a cast to do it.

    Conversion from T[] to T* happens automaticalliy in most contexts, so given

    int a1[N];

    you can just write:

    mtxrot1d(a1);

    If you have, say, a 3-dimensional array of T, you can obtain
    the first T object in the array via indexing:

    a3[0][0][0]

    and its address with an "&" operator:

    &a3[0][0][0]

    The latter could be "simplified" to this:

    a3[0][0]

    assuming it's used in a context that triggers the usual
    array-to-pointer conversion ("decay"), but I find &a3[0][0][0]
    to be clearer.

    --
    Keith Thompson (The_Other_Keith) <>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Apr 28, 2008
    #7
  8. wrote:
    > Is it always legal to cast expressions of type of multi-dimension
    > array to type of pointer?
    > Including:
    > T[] to T* ,
    > T[][] to T* ,
    > T[][][] to T* ,
    > and so on...
    >
    > For example:
    > int *mtxrot1d(int *p, int n);
    > int a2[N][N];
    > int a3[N][N][N];
    >
    > mtxrot1d((int*)a2);
    > mtxrot1d((int*)a3);


    If you want &a3[0][0][0], then you need only write that.

    Apart from the direct conversion from int (*)[][] to int *
    being technically undefined, if we take the most obvious
    result to be one of 'repeated' decay, i.e. &a[0]...[0],
    then you still face the problem that _that_ pointer can
    only access the elements of the inner most array
    (in the above samples, N elements).

    --
    Peter
    Peter Nilsson, Apr 28, 2008
    #8
    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. Adam Hartshorne

    Multi-Dimension Array Question

    Adam Hartshorne, Jun 8, 2005, in forum: C++
    Replies:
    6
    Views:
    2,133
  2. Makiyo
    Replies:
    3
    Views:
    530
    Richard Heathfield
    Feb 22, 2004
  3. Eric Laberge

    Multi-dimension array assignments

    Eric Laberge, Aug 22, 2005, in forum: C Programming
    Replies:
    3
    Views:
    449
    Dave Thompson
    Aug 27, 2005
  4. Luuk
    Replies:
    15
    Views:
    800
    Nobody
    Feb 11, 2010
  5. Hansen
    Replies:
    3
    Views:
    1,082
    rep_movsd
    Apr 24, 2010
Loading...

Share This Page