473,320 Members | 1,695 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Pointer to qualified poitner to qualified object

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
14 1944
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
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
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
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
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
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
"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
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
"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
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
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
"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
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
"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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
by: Ellarco | last post by:
``Opaque-pointer representing the ID of an object. struct _objID; typedef struct _objID * objectID;'' Hi again. Im using an api that defines an objectID type. The above represents the extent...
4
by: Steven T. Hatton | last post by:
I mistakenly set this to the comp.std.c++ a few days back. I don't believe it passed the moderator's veto - and I did not expect or desire anything different. But the question remains: ISO/IEC...
7
by: Michael Birkmose | last post by:
Hi everyone!, Are pointers to incomplete types allowed in ANSI C? I can see that pointer arithmic on pointers to incomple types is impossible, however there are situations where it can be...
16
by: junky_fellow | last post by:
According to Section A6.6 Pointers and Integers (k & R) " A pointer to one type may be converted to a pointer to another type. The resulting pointer may cause addressing exceptions if the...
204
by: Alexei A. Frounze | last post by:
Hi all, I have a question regarding the gcc behavior (gcc version 3.3.4). On the following test program it emits a warning: #include <stdio.h> int aInt2 = {0,1,2,4,9,16}; int aInt3 =...
41
by: Alexei A. Frounze | last post by:
Seems like, to make sure that a pointer doesn't point to an object/function, NULL (or simply 0) is good enough for both kind of pointers, data pointers and function pointers as per 6.3.2.3: 3 An...
18
by: hzmonte | last post by:
typedef int t_compare_func(const void *, const void *); struct node *tree_search(struct node *root, const void *keyy, t_compare_func *comp) { struct node *cur_item; int result; if (root ==...
5
by: max | last post by:
Dear all, I did the following analysis to conclude that the following pointer types are not compatible. Please let me know If my analysis and interpretation of the C standard are correct: ...
17
by: Pietro Cerutti | last post by:
i Group, to my understanding, defining a function parameter as "const" means that the function is not going to change it. Why does the compiler says "return discards qualifiers from pointer...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.