On Sep 17, 3:02 am, Nick Keighley <
[email protected]>
wrote:
On 16 Sep, 21:14, (e-mail address removed) wrote: ...
Besides, void * seems more natural for this kind
of task.
rubbish
Why is it rubbish? If you have a void pointer, it will typically point
to any kind of object: int, double, long long, structures, anything.
Does it seem natural to you to treat such an object as if it were a
*character*?
Tracing back, "this kind of task" refers to:
int a[20];
void *b;
b = (void *)a; // b points to a[0]
b += 5*sizeof(*a); // b points to a[5]
In this case, 'b' is being used as a pointer to char, because the amount
that is being added to is a number of bytes, not a number of ints. That
being the case, it should be declared as char*, not void*.
It depends on what you want to do with it. If you're going to
dereference it to examine the representation of whatever it points to,
then yes, unsigned char* is better than char*. If you're not going to
dereference it, it doesn't matter whether you use char* or unsigned
char*; both have the same stride, 1 byte.
But the use of the expression "5*sizeof(*a)" indicates that the actual
intent is advance the pointer by 5 ints. The type int* will do
exactly that.
It's impossible to tell from the short snippet what the intent is, but
it does nothing that couldn't be done more conveniently, and with less
risk of error, than this:
int a[20];
int *b;
b = a; /* b points to a[0] */
b += 5; /* b points to a[5] */
Maybe there's some reason for b to be a void* rather than an int*, but
it's not evident from what's been posted so far.
Shouldn't it be unsigned char *? Anyway, my argument was that if your
compiler can perform arithmetic with the void *, then go void *, as
you did above.
That advice is questionable, in my opinion, even if you're only
concerned with gcc. But if you're writing code for, for example, the
Linux kernel, which has no pretense of portability to compilers other
than gcc, then I suppose it's not too bad.
The advice is very bad if there's any possibility that the code will
need to be compiled with something other than gcc.
If you have a void* pointer object, and you want to advance it by N
bytes, it is in my opinion *better* to write:
ptr = (char*)ptr + N;
because it's portable, and because it expresses the idea that you're
doing something that doesn't make sense for void*.
But it will have a different effect when incremented (it will advance
to the next int, say four bytes later) or dereferenced (it fetch a,
say, 32-bit int, rather than an 8-bit char).
Of course it will. That's the point. If you're accessing an array of
int, a pointer of type int* is the best way to do it. You *can* use
void* or unsigned char*, but then you have to write additional code
(casting pointers, multiplying offsets by sizeof(int)).
If you need to access the individual bytes of an array of int, then
void* or unsigned char* is better, but that's a fairly unusual
requirement.
If you show us a problem you need to solve, involving an array of int,
for which int* pointers are not adequate, please do so, and we can
discuss the best way to go about it.