I have a question about coding styles when using void pointers.
This code is modified from code geeks
#include<stdio.h>
int main()
{
int a[2] = {1, 2};
void *ptr = &a;
for(int i=0; i<2; i ) {
printf("%d\n", *(int *)ptr i);
}
return 0;
}
I am using a generic circular buffer in my project. This buffer has a void pointer to a static buffer which is passed in during initialization. I want to traverse and print the data in the circular buffer. I was unsure how to print the contents until I found the code above.
I have two questions:
- Is this an appropriate well accepted way to traverse my data? Will tools such as PC-Lint throw a warning with good reason?
- Is there a better way to traverse this data?
Edit: Thanks to Lev M. I have updated my code to properly traverse the data using the size of the data type. The circular buffer is meant to be generic meaning we pass in a buffer and a data type size.
The updated test code is as follows.
#include<stdio.h>
int main()
{
int a[2] = {2, 1};
void *ptr = &a;
for(int i=0; i<2; i ) {
printf("%d\n", *(int *)ptr);
ptr = ptr sizeof(int);
}
return 0;
}
CodePudding user response:
There is a major bug in your code:
printf("%d\n", *(int *)ptr i);
The operator precedence means this statement will first do *(int*)ptr
than add 2 to the value in the first cell of the array.
If you actually wanted to traverse the array, you would need to do this:
printf("%d\n", *(int *)(ptr i));
But, that would immediately throw a compiler warning:
warning: pointer of type ‘void *’ used in arithmetic [-Wpointer-arith]
This is for a very good reason: to do pointer arithmetic, your compiler needs to know the size of the data being pointed to.
But void
has no size for its data, there for this is illegal in standard C.
It is supported by some compiler extensions: http://gcc.gnu.org/onlinedocs/gcc-4.8.0/gcc/Pointer-Arith.html
But note than in case of GCC, the size is 1, so your array will be treated as array of char
not int
.
How to traverse the buffer in your application will depend on whether the data in it is uniform or not.
You will need to present actual data example if you want a working traversal solution.
CodePudding user response:
I'm not sure what you want to do we this array but basically the way you can't 'use' void* unless you convert it to its true type. To do so what you wrote above is just fine ((int*)ptr) once you did that you can use this to do any legal operation you want with this 'int' pointer.