Is this tricky Pointer casting ?

Go To Last Post
13 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

ive been writing a few C functions in some other ide for developing. (non-gnu).
All code ran fine, compiled good, in short it was working according to expectations.
Today (2007-06-24) Downloaded the most recent WinAVR-20070525 package.
All looked good till I added the a function with the following line:

Buffer is of type void*

(u_int8*)FA->C.Buffer += (FA->C.Volume->BytesPerSec);
[error: invalid lvalue in assignment]

And managed to make it accept the code by omitting the type cast :shock:

/*(u_int8*)*/ FA->C.Buffer += (FA->C.Volume->BytesPerSec);

My question is, is this behaviour is known? Or is it me lacking on C.

advise is highly appreciated.

//Steven

MY MICROCONTROLLER CAN BEAT THE HELL OUT OF YOUR MICROCONTROLLER /ATMEL

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

> Or is it me lacking on C.

Yes, it is.

GCC used to accept the typecast on the left-hand side until version
4, but it's never been correct C. A typecast does not produce an
lvalue.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Jörg,

Ok im eager to know the right way to increase the address where the void pointer is pointing to.

Without is the right was as gcc automatically type-casts it? but to which type?

where can I read this up in detail.

MY MICROCONTROLLER CAN BEAT THE HELL OUT OF YOUR MICROCONTROLLER /ATMEL

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The full form would be

*(u_int8*)FA->C.Buffer = *(u_int8*)FA->C.Buffer + FA->C.Volume->BytesPerSec;

I don't think this can be simplified in legal C. If FA->C.Buffer is
meant to represent a pointer to uint8_t objects, why not simply
declare it that way?

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks Jörg,

is it ok to state "Don't use += with void pointers" ?

MY MICROCONTROLLER CAN BEAT THE HELL OUT OF YOUR MICROCONTROLLER /ATMEL

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MaxK, you can generalize (like Jörg aleady stated): never typecast the left side of an assignment.
Thus, you'd need to do something like:

u_int8* bptr = (u_int8*) FA->C.Buffer;
*bptr += FA->C.Volume->BytesPerSec;

Edit
As for adding void pointers, I'd have to review the C89 specs. But, I believe you're allowed to do so. Incrementing a void pointer, IIRC, increases its value by 1. So,

void *a = (void*) 1;
a += 2;
// a should now contain 3

as opposed to

u_int16* a = (u_int16*) 1;
a += 2;
// c should now contain 5
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

> As for adding void pointers, I'd have to review the C89 specs.

void pointers don't have any defined arithemetics.

It's simply a GCC extension to treat void pointer arithmetics
same as byte pointer arithmetics, but that's obviously not
portable.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the clarification, Jörg!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
The full form would be

*(u_int8*)FA->C.Buffer = *(u_int8*)FA->C.Buffer + FA->C.Volume->BytesPerSec; 


Not sure what that would do exactly, are you sure about that Jörg?

Would not just

FA->C.Buffer = (u_int8*)FA->C.Buffer + FA->C.Volume->BytesPerSec; 

be ok?

/Lars

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Lajon wrote:
Would not just

FA->C.Buffer = (u_int8*)FA->C.Buffer + FA->C.Volume->BytesPerSec; 

be ok?

Definitely not. That assigns the value of your sum to your value of your pointer. You need a pointer dereference on the left side to assign the sum to the memory location that your pointer is pointing to.

Edit
Lars pointed out the above statement is incorrect.

Last Edited: Tue. Jun 26, 2007 - 12:00 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What? The original problem is about incrementing the pointer, no pointer dereferencing going on here:

(u_int8*)FA->C.Buffer += (FA->C.Volume->BytesPerSec);

/Lars

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Lars, right you are. I was tripped up by C's syntatic density and had thought the original problem was:

*(u_int8*)FA->C.Buffer += (FA->C.Volume->BytesPerSec);
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hmm never knew/realized type-casting on the left side was depreciated.

Ok, as what Jörg has been opted before,
to sort this (elegant) is to change the Buffer from void* to unsigned char* and '+=' can be used without the need of typecasting the left side of the assignment.

No?

MY MICROCONTROLLER CAN BEAT THE HELL OUT OF YOUR MICROCONTROLLER /ATMEL