Pointer arithmetic: char* vs. void*
Author |
Message |
Clint Olse #1 / 6
|
 Pointer arithmetic: char* vs. void*
I'm playing around with an array ADT, and the following came to mind: If you have a block of data allocated by calloc, and you want access to the ith element, you calculate an offset from the base pointer by (index * sizeof (elem)). Is it safe for this base pointer to be of type void* or should it be char*? In most examples posted here, any time you want to do explicit arithmetic via bytes a cast was always made to char*. Gcc -Wall happily reports sizeof (void) to be 1, however throwing the -ansi -pedantic switches does issue a warning about trying to use this operator on a void type. Is gcc being compliant? Thanks, -Clint
|
Mon, 26 Sep 2005 00:37:57 GMT |
|
 |
Eric Sosma #2 / 6
|
 Pointer arithmetic: char* vs. void*
Quote:
> I'm playing around with an array ADT, and the following came to mind: > If you have a block of data allocated by calloc, and you want access to the > ith element, you calculate an offset from the base pointer by (index * > sizeof (elem)). Is it safe for this base pointer to be of type void* or > should it be char*? In most examples posted here, any time you want to do > explicit arithmetic via bytes a cast was always made to char*. > Gcc -Wall happily reports sizeof (void) to be 1, however throwing the -ansi > -pedantic switches does issue a warning about trying to use this operator > on a void type. > Is gcc being compliant?
"Yes." (Or, more helpfully, "In the latter case, yes.") --
|
Mon, 26 Sep 2005 01:12:52 GMT |
|
 |
Ryan Henness #3 / 6
|
 Pointer arithmetic: char* vs. void*
Quote:
> I'm playing around with an array ADT, and the > following came to mind: > If you have a block of data allocated by calloc, and > you want access to the ith element, you calculate an > offset from the base pointer by (index * sizeof (elem)). > Is it safe for this base pointer to be of type void* or > should it be char*? In most examples posted here, any > time you want to do explicit arithmetic via bytes a > cast was always made to char*.
Nope. Pointer arithmetic is not defined for the void* type. Here's the relevant quote: 3.3.6 Additive operators Constraints For addition, either both operands shall have arithmetic type, or one operand shall be a pointer to an ^^^^^^^^^^^^^^^ object type and the other shall have integral type. ^^^^^^^^^^^ Note that a void* is a pointer to an "incomplete" type, which is distinct from an object type. Arithmetic is not defined for pointers to incomplete types, because the size of an imcomplete type is not known. Quote: > Gcc -Wall happily reports sizeof (void) to be 1,
This is a gcc-ism. Here's what my Sun Forte compiler says about sizeof(void): /tmp[78]> cat void.c #include <stdio.h> int main(void) { printf("%lu\n", (unsigned long)sizeof(void)); Quote: }
/tmp[79]> cc void.c "void.c", line 4: cannot take sizeof void cc: acomp failed for void.c Attempting to take sizeof(void) causes translation to fail for this program. Quote: > however throwing the -ansi -pedantic switches does > issue a warning about trying to use this operator > on a void type.
Yes. sizeof(void) violates a constraint, which means it *requires* a diagnostic. A warning is a valid form of diagnostic. So is the error I've shown above. Quote: > Is gcc being compliant?
Having correctly diagnosed the code (when invoked with all of those switches), gcc is in compliance (when invoked with all those switches). HTH, Ryan.
|
Mon, 26 Sep 2005 01:33:09 GMT |
|
 |
Dan P #4 / 6
|
 Pointer arithmetic: char* vs. void*
Quote: >I'm playing around with an array ADT, and the following came to mind: >If you have a block of data allocated by calloc, and you want access to the >ith element, you calculate an offset from the base pointer by (index * >sizeof (elem)). Is it safe for this base pointer to be of type void* or >should it be char*? In most examples posted here, any time you want to do >explicit arithmetic via bytes a cast was always made to char*.
It is *impossible* to perform pointer arithmetic on void pointers and the reason should be obvious to anyone thinking about it. Hint: what is the size of an incomplete type? (void is an incomplete type.) Quote: >Gcc -Wall happily reports sizeof (void) to be 1, however throwing the -ansi >-pedantic switches does issue a warning about trying to use this operator >on a void type. >Is gcc being compliant?
Yes, when invoked in conforming mode (-ansi -pedantic). Your incorrect attempt to obtain the size of void requires a diagnostic and you got it. You have several options: 1. Use ADT pointers, if the complete definition of the ADT is available to your program. 2. If it isn't, but its size is available as a constant expression, you can do the following: typedef char PADT[ADTsize]; and use PADT pointers instead (PADT stands for pseudo-ADT). 3. If the size is not available as a constant expression, use char pointers. The first two methods have the advantage that you don't have to do any index arithmetic, the compiler will do it for you, just as in the case of ordinary types. Dan -- Dan Pop DESY Zeuthen, RZ group
|
Mon, 26 Sep 2005 00:58:20 GMT |
|
 |
Yusuf Motiwal #5 / 6
|
 Pointer arithmetic: char* vs. void*
Although most compileres allows aritmetic on void *, it is non compliant. It may be safe to have base pointer void * but during arithmetic operation, you should cast it to appropriate type. If not, i think, it may make your code non-portable. In my opinion, GCC is most compliant to standard compate to other compilers but I may be wrong. Regards, Yusuf
Quote: > I'm playing around with an array ADT, and the following came to mind: > If you have a block of data allocated by calloc, and you want access to the > ith element, you calculate an offset from the base pointer by (index * > sizeof (elem)). Is it safe for this base pointer to be of type void* or > should it be char*? In most examples posted here, any time you want to do > explicit arithmetic via bytes a cast was always made to char*. > Gcc -Wall happily reports sizeof (void) to be 1, however throwing the -ansi > -pedantic switches does issue a warning about trying to use this operator > on a void type. > Is gcc being compliant? > Thanks, > -Clint
|
Mon, 26 Sep 2005 15:19:28 GMT |
|
 |
Joseph Giro #6 / 6
|
 Pointer arithmetic: char* vs. void*
Quote: > Although most compileres allows aritmetic on void *, it is non compliant. It > may be safe to have base pointer void * but during arithmetic operation, you > should cast it to appropriate type. If not, i think, it may make your code > non-portable.
One has two big possibilities here: - either do the standard C arithmetic on pointer, not in terms of bytes, but of elements. For example: myType_t *p = calloc(sizeof(myType_t), N); // *p is the first elem as is p[0], *(p + n) is the (n+1)th as is p[n] // the address of the first element is p, the address of the (n+1)th is either p+n or &(p[n]) -- which do you chose? - or for some reason you really want to "do it yourself", then, as Yusuf points out, void * is not compliant, but casting to char * is, however, on IBM's OS/390 C compiler you get an Informational message (with the chekout option), because casting pointers is no completely good; there is a 3rd possibilty, which is to convert to and from int and that is the most academic.
|
Wed, 28 Sep 2005 01:12:05 GMT |
|
|
|