4

I have a question about pointer casting for C.

if I have a function with this signature:

uint8_t input_getc(void)

which reads user input from STDIN.

Then I have a pointer

void* buffer

that I store return values from input_getc() in. What would be the proper way to cast this?

//read user input
for(i = 0; i < SIZE; ++i)
{
    uint8_t temp = input_getc();

    //copy to void* buffer
    *(uint8_t *)(buffer + i) = temp //WAY #1
    *(buffer + i) = (void *)temp;   //WAY #2
}

Are both of these the same?

Thanks

Hunter McMillen
  • 59,865
  • 24
  • 119
  • 170

3 Answers3

8

As it is right now, neither of those methods will compile. Since buffer is a void* you can't do arithmetic on it since it has an unknown size.

It's not entirely clear exactly where you are trying to store it. If you're just trying to store the uint8_t into the memory location pointed by buffer with offset i, then it can be done like this:

((uint8_t*)buffer)[i] = temp;

EDIT :

Okay, apparently arithmetic on void* is allowed in C, but not in C++. However, doing so it still considered unsafe behavior.

See this question: Pointer arithmetic for void pointer in C

Community
  • 1
  • 1
Mysticial
  • 464,885
  • 45
  • 335
  • 332
  • -1 you can not dereferencing void* pointer but you can do arrithmetic operation with pointer value (not its pointe value) see this link http://codepad.org/7YHCYz5Q – Jeegar Patel Nov 17 '11 at 05:41
  • 1
    @Mr.32: I disagree. Just because GCC allows it doesn't mean it's what the standard says. As I have already demonstrated, VS2010 rejects arithmetic on void pointers. – Mysticial Nov 17 '11 at 05:44
  • @Mysticial lets find out what is truth in standard c language draft – Jeegar Patel Nov 17 '11 at 05:46
  • 1
    @Mr.32: I just double-checked this. In C it's allowed, but in C++, it is forbidden. I'll update my answer to address this. So yes, you are right. – Mysticial Nov 17 '11 at 05:49
  • @Mysticial if you have any snipped shot from standard c language draft then also put that i will upvote ur answer..!! – Jeegar Patel Nov 17 '11 at 05:52
  • @Mr.32: See this question: (http://stackoverflow.com/questions/3523145/pointer-arithmetic-for-void-pointer-in-c) So it looks like GCC allows it, but it is still considered unsafe. But the answers are still very conflicting. – Mysticial Nov 17 '11 at 05:56
  • @Mysticial yea you seems right because i am also not getting something perfect/standard about that. – Jeegar Patel Nov 17 '11 at 06:00
  • 2
    @Mr.32, for the standard pointer arithmetic is only allowed for "pointers to object type", which is the terminology of the standard for the opposite of "incomplete type". `void*` is explicitly defined to be a pointer to an incomplete type. And the reasoning for that is simple, what would the byte increment be? 1 (as `char`) or the most convenient word size of the platform? So no, for standard C this is undefined behavior, but gcc (and some gcc like derivatives) accept this as an extension. – Jens Gustedt Nov 17 '11 at 07:18
2

One way to do this is:

*(((uint8_t*)buffer)+i) = temp;
Seth Carnegie
  • 73,875
  • 22
  • 181
  • 249
Jason Kuang
  • 261
  • 2
  • 8
2

i am not understanding what do you mean by

 copying to  `void* buffer`

but if you are doing following thing then way1 is right

int main()
{
    int i;
    char a[10];
    void *buffer;
    buffer = &a;   // buffer is void* type pointer and its pointing to some buffer then
    for(i = 0; i < 10; ++i)
    {
        uint8_t temp = 65;

        //copy to void* buffer
        *(uint8_t *)(buffer + i) = temp; //WAY #1

    }
    printf("\n %s",a);
}

BIG Edit :

IN WAY1

you are adding +i offcet with void * buffer and still whole result is void* then you are typecasting that whole result with uint8_t* then accesing that value so it works

but in way2 you are adding +i offcet with void * buffer still whole result is void* and then you are accesing that value ...which is completely wrong.. you will get warning/error here

 warning: dereferencing ‘void *’ pointer

One more Edit :

you can not dereferencing void* pointer but you can do arrithmetic operation with pointer value (not its pointe value)

Jeegar Patel
  • 26,264
  • 51
  • 149
  • 222
  • 1
    Thanks, this is what I was doing. I know that this works because I took it from a piece of working code. But I was wondering if method two was better practice. + 1 – Hunter McMillen Nov 17 '11 at 05:24
  • Actually, no, this won't compile. You can't do `buffer + i` because you can't do arithmetic on a `void*`. On VS2010 the error is: `error C2036: 'void *' : unknown size` – Mysticial Nov 17 '11 at 05:27
  • @Mysticial in gcc i dont have any error...you can not dereferencing void* pointer but you can do arrithmetic operation with pointer value (not its pointe value) okey – Jeegar Patel Nov 17 '11 at 05:38
  • @HunterMcMillen way1 is completely right so go ahead with that..way2 is totaly wrong okey – Jeegar Patel Nov 17 '11 at 05:45
  • 1
    I'll +1 this, then since we're both right and that talk has been very constructive. – Mysticial Nov 17 '11 at 06:02