two dimensional arrays:

F

Flash Gordon

Dag-Erling Smørgrav said:
I believe void * is required to be assignment compatible with any
other kind of pointer except a function pointer.
Indeed.

I believe the point Pete was making,

I believe that Pete and I are in complete agreement.
> however, is that you are not
permitted to access an object through a pointer to anything but the
object's type, a compatible type, or char.

There are several cases where the standard allows you to assign a
pointer to another pointer type (some where a cast is required) and you
are guaranteed to get what you would expect. However, those cases don't
guarantee you can read that pointer (through another pointer) as a
pointer to a different type. Specifically, void* and char* are
guaranteed to have the same representation, but pointers to structs are
not guaranteed to have the same representation as pointers to void.
> Pointers to void are not
used to access anything; they are always cast or assigned to some
other pointer type before use.

Yes, but irrelevant to what we were discussing.
 
A

Axter

Dag-Erling Smørgrav said:
I believe void * is required to be assignment compatible with any
other kind of pointer except a function pointer.

I believe the point Pete was making, however, is that you are not
permitted to access an object through a pointer to anything but the
object's type, a compatible type, or char. Pointers to void are not
used to access anything; they are always cast or assigned to some
other pointer type before use.

I don't think that's the point he was trying to make, because it would
not apply to the code I posted.
The code I posted has it cast to the target pointer via the macro.
http://code.axter.com/allocate2darray.h
http://code.axter.com/allocate2darray.c

If I'm not mistaken, what he's trying to say is that there could be a
system in which sizeof(void*) is different then sizeof(foo*).

Now I can't see how a pointer could be a different size for one type VS
another type.

I can't see how a system could possibly function that way.

You could have a system in which a local pointer is a different size
then a far pointer, however, it would still be the case that all local
pointer types would be the same size.

And I still don't see where in the standard, it speaks of the
possibility of pointers having different size for different types.
 
P

pete

Flash said:
I believe that Pete and I are in complete agreement.

I think so too.
There are several cases where the standard allows you to assign a
pointer to another pointer type (some where a cast is required)
and you
are guaranteed to get what you would expect.
However, those cases don't
guarantee you can read that pointer (through another pointer) as a
pointer to a different type. Specifically, void* and char* are
guaranteed to have the same representation,
but pointers to structs are
not guaranteed to have the same representation as pointers to void.


Yes, but irrelevant to what we were discussing.

Here's the code again:

#define ALLOCATE2DARRAY(Type, x, y) \
(Type**)Allocate2DArray(sizeof(Type), x, y)

void **Allocate2DArray(int TypeSize, int x, int y)
{
void **ppi = malloc(x*sizeof(void*));
void *pool = malloc(x*y*TypeSize);
unsigned char *curPtr = pool;
int i;
for(i = 0; i < x; i++)
{
*(ppi + i) = curPtr;
curPtr += y*TypeSize;
}
return ppi;
}

ppi[0] is the first element in an array of pointer to void.
ppi[1] is the second element in an array of pointer to void.

After:
float **My2DFloat = ALLOCATE2DARRAY(float, x, y);

My2DFloat[0] is the first element in an array of pointer to float.

The difference of
(char *)&My2DFloat[1] - (char *)&My2DFloat[0]
is sizeof(float *) bytes

The difference of
(char *)&ppi[1] - (char *)&ppi[0]
is sizeof(void *) bytes

If sizeof (float *) does not equal sizeof (void *),
then My2DFloat[1] derferences the middle of a pointer.
 
P

pete

Axter wrote:
And I still don't see where in the standard, it speaks of the
possibility of pointers having different size for different types.

You interpret this as a guarantee
that all pointers have the same size?

N869
6.2.5 Types
[#27]

Pointers to other types need
not have the same representation or alignment requirements.
 
A

Axter

pete said:
Axter said:
And I still don't see where in the standard, it speaks of the
possibility of pointers having different size for different types.

You interpret this as a guarantee
that all pointers have the same size?

N869
6.2.5 Types
[#27]

Pointers to other types need
not have the same representation or alignment requirements.
It's actually in section #26.

After reading this section, I have to agree with you, in that it's
possible for a C compliant compiler to have sizeof(void*) not equal
sizeof(foo*)
I'm not aware of any such compiler, or system, but none the less, the
code is not portable as-is.
 
K

Keith Thompson

Axter said:
If I'm not mistaken, what he's trying to say is that there could be a
system in which sizeof(void*) is different then sizeof(foo*).
Yes.

Now I can't see how a pointer could be a different size for one type VS
another type.

I can't see how a system could possibly function that way.

You could have a system in which a local pointer is a different size
then a far pointer, however, it would still be the case that all local
pointer types would be the same size.

Imagine a system in which machine addresses point to words (where a
word is several octets), but you want to support 8-bit bytes. A word
pointer doesn't have enough information to specify a single byte, so
you invent an artificial byte pointer, consisting of a native word
pointer plus the offset of the byte within the word. Types void* and
char* would have to be implemented as a composite byte pointer, but
int* could be a (smaller) word pointer.

(The C implementation on Cray vector machines is very much like this,
except that the offset is stored in the unused upper bits of the
machine address. Types void* and char* have the same size but
different representations. The AS/400 is even more exotic, but I
don't remember the details.)
And I still don't see where in the standard, it speaks of the
possibility of pointers having different size for different types.

Why should it say so explictly? If it doesn't guarantee (explictly or
implicitly) that all pointers are the same size, it's legal for them
to be of different sizes.
 
K

Keith Thompson

Keith Thompson said:
Why should it say so explictly? If it doesn't guarantee (explictly or
implicitly) that all pointers are the same size, it's legal for them
to be of different sizes.

I seem to have invented a new word. Just to keep things simple, let's
assume that "explictly" is a synonym for "explicitly".
 
P

pete

Keith Thompson wrote:
(The C implementation on Cray vector machines is very much like this,
except that the offset is stored in the unused upper bits of the
machine address. Types void* and char* have the same size but
different representations.

"void* and char* have different representations" is not C.
 
K

Keith Thompson

pete said:
"void* and char* have different representations" is not C.

Oops. I meant void* and char* (which have the same representation)
vs. int* (which has a different representation). Thanks for catching
that.
 
D

Default User

Barry said:
On 1 May 2005 04:55:32 -0700, "Axter" <[email protected]> wrote:

[93 lines of quotes, some EIGHT deep, snipped]
fail.

Not at all. We can conclude that your code WILL FAIL whenever
sizeof(void*) is different from sizeof(coordpt*) or whenever they have
different representations of the value.


For future conversations, could you and Axter do everyone a favor and
learn how to trim your posts?

That was ridiculous.



Brian
 
B

Barry Schwarz

I don't think that's the point he was trying to make, because it would
not apply to the code I posted.
The code I posted has it cast to the target pointer via the macro.
http://code.axter.com/allocate2darray.h
http://code.axter.com/allocate2darray.c

If I'm not mistaken, what he's trying to say is that there could be a
system in which sizeof(void*) is different then sizeof(foo*).

Now I can't see how a pointer could be a different size for one type VS
another type.

I can't see how a system could possibly function that way.

But the language standard is not constrained by the limits of your
imagination. If you want to write portable code, you don't make
assume any consistency that is not guaranteed by the standard. Look
at all the people who code
if x >= 'a' && x <= 'z'
because in ASCII the letters are contiguous.
You could have a system in which a local pointer is a different size
then a far pointer, however, it would still be the case that all local
pointer types would be the same size.

And I still don't see where in the standard, it speaks of the
possibility of pointers having different size for different types.

Only because you refuse to read the references already provided.
Section 6.2.5-27. Check the last sentence. The size of a pointer is
a part of how it represents its value.

"A pointer to void shall have the same representation and alignment
requirements as a pointer to a character type. Similarly, pointers to
qualified or unqualified versions of compatible types shall have the
same representation and alignment requirements. All pointers to
structure types shall have the same representation and alignment
requirements as each other. All pointers to union types shall have the
same representation and alignment requirements as each other. Pointers
to other types need not have the same representation or alignment
requirements."



<<Remove the del for email>>
 
L

Lawrence Kirby

On Mon, 02 May 2005 01:18:11 +0000, pete wrote:

....
Here's the code again:

#define ALLOCATE2DARRAY(Type, x, y) \
(Type**)Allocate2DArray(sizeof(Type), x, y)

void **Allocate2DArray(int TypeSize, int x, int y)
{
void **ppi = malloc(x*sizeof(void*));
void *pool = malloc(x*y*TypeSize);
unsigned char *curPtr = pool;
int i;
for(i = 0; i < x; i++)
{
*(ppi + i) = curPtr;
curPtr += y*TypeSize;
}
return ppi;
}

This looks fine, it allocates an array of x void * pointers and in effect
sets each of those to point to an array of y objects of TypeSize bytes
each.
ppi[0] is the first element in an array of pointer to void. ppi[1] is
the second element in an array of pointer to void.

After:
float **My2DFloat = ALLOCATE2DARRAY(float, x, y);

The cast in the macro is the source of potential problems from here on.
My2DFloat[0] is the first element in an array of pointer to float.

That is correct to a degree since we are assuming that float * and void *
have the same size. However the standard does NOT guarantee that float *
and void * use the same representation even if they have the same size.
What that means is that the void * values we've set the array up with are
not garanteed to be suitable to be accessed as float * values. We could
write new float * values to the array and then use those with no problem,
but we cannot portably access the existing void * values using My2DFloat,
unless we cast it back to void ** (or something similar). And "portable"
in that context is still based on our assumption about the sizes of void *
and float *.
The difference of
(char *)&My2DFloat[1] - (char *)&My2DFloat[0]
is sizeof(float *) bytes

The difference of
(char *)&ppi[1] - (char *)&ppi[0]
is sizeof(void *) bytes

If sizeof (float *) does not equal sizeof (void *), then My2DFloat[1]
derferences the middle of a pointer.

But code following this such as:

My2DFloat[0][0] = 0.0;

remains non-portable even if float * and void * have the same size,
because it is not converting between void * and float *, it is
reinterpreting the bit pattern of a void * as if it is a float *.

Lawrence
 
A

Al Bowers

Lawrence said:
This looks fine, it allocates an array of x void * pointers and in effect
sets each of those to point to an array of y objects of TypeSize bytes
each.

It also looks risky since one is assuming function malloc
will always return a pointer to storage, never returning
NULL.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,133
Latest member
MDACVReview
Top