By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,290 Members | 1,671 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,290 IT Pros & Developers. It's quick & easy.

Pointer to qualified poitner to qualified object

P: n/a
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
Jun 27 '08 #1
Share this Question
Share on Google+
14 Replies


P: n/a
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];

void func(tmp_tensor3 *d3array);

int main(void)
{
double array[DIM_1][DIM_2][DIM_3];
int c1, c2, c3;

for (c1 = 0; c1 != DIM_1; ++c1)
for (c2 = 0; c2 != DIM_2; ++c2)
for (c3 = 0; c3 != DIM_3; ++c3) {
array[c1][c2][c3] = c1 + c2 + c3 + 0.5;
}
func(array);
return 0;
}

void func(tmp_tensor3 *d3array)
{
int c1, c2, c3;

for (c1 = 0; c1 != DIM_1; ++c1) {
for (c2 = 0; c2 != DIM_2; ++c2){
for (c3 = 0; c3 != DIM_3; ++c3) {
printf("%f ", d3array[c1][c2][c3]);
}
putchar('\n');
}
putchar('\n');
}
putchar('\n');
}

/* END new.c */
--
pete
Jun 27 '08 #2

P: n/a
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

Jun 27 '08 #3

P: n/a
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[i];
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[i];
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
Jun 27 '08 #4

P: n/a
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
Jun 27 '08 #5

P: n/a
Flash Gordon <sp**@flash-gordon.me.ukwrites:
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) ks***@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"
Jun 27 '08 #6

P: n/a
On Fri, 30 May 2008 07:31:54 UTC, Szabolcs Borsanyi
<s.********@sussex.ac.ukwrote:
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!
Jun 27 '08 #7

P: n/a
"Herbert Rosenau" <os****@pc-rosenau.dewrites:
[...]
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) ks***@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"
Jun 27 '08 #8

P: n/a
On Mon, 2 Jun 2008 20:35:24 UTC, Keith Thompson <ks***@mib.orgwrote:
"Herbert Rosenau" <os****@pc-rosenau.dewrites:
[...]
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!
Jun 27 '08 #9

P: n/a
"Herbert Rosenau" <os****@pc-rosenau.dewrites:
On Mon, 2 Jun 2008 20:35:24 UTC, Keith Thompson <ks***@mib.orgwrote:
>"Herbert Rosenau" <os****@pc-rosenau.dewrites:
[...]
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) ks***@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"
Jun 27 '08 #10

P: n/a
On May 30, 7:31 pm, Szabolcs Borsanyi <s.borsa...@sussex.ac.ukwrote:
>
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).
Jun 27 '08 #11

P: n/a
On Wed, 4 Jun 2008 21:00:02 UTC, Keith Thompson <ks***@mib.orgwrote:
"Herbert Rosenau" <os****@pc-rosenau.dewrites:
On Mon, 2 Jun 2008 20:35:24 UTC, Keith Thompson <ks***@mib.orgwrote:
"Herbert Rosenau" <os****@pc-rosenau.dewrites:
[...]
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!
Jun 27 '08 #12

P: n/a
"Herbert Rosenau" <os****@pc-rosenau.dewrites:
On Wed, 4 Jun 2008 21:00:02 UTC, Keith Thompson <ks***@mib.orgwrote:
>"Herbert Rosenau" <os****@pc-rosenau.dewrites:
On Mon, 2 Jun 2008 20:35:24 UTC, Keith Thompson <ks***@mib.orgwrote:
"Herbert Rosenau" <os****@pc-rosenau.dewrites:
[...]
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) ks***@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"
Jun 27 '08 #13

P: n/a
On Thu, 5 Jun 2008 21:22:52 UTC, Keith Thompson <ks***@mib.orgwrote:
"Herbert Rosenau" <os****@pc-rosenau.dewrites:
On Wed, 4 Jun 2008 21:00:02 UTC, Keith Thompson <ks***@mib.orgwrote:
"Herbert Rosenau" <os****@pc-rosenau.dewrites:
On Mon, 2 Jun 2008 20:35:24 UTC, Keith Thompson <ks***@mib.orgwrote:
"Herbert Rosenau" <os****@pc-rosenau.dewrites:
[...]
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!
Jun 27 '08 #14

P: n/a
"Herbert Rosenau" <os****@pc-rosenau.dewrites:
[...]
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) ks***@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"
Jun 27 '08 #15

This discussion thread is closed

Replies have been disabled for this discussion.