Pointer casting in GCC 4

A

Arne Schmitz

Why does this code not compile in GCC 4.x:

int
main()
{
int a[100];
void *pa = (void *)a;

((char*)pa) += 2;

return 0;
}

In GCC 3.3 it still worked.

Arne
 
M

Maxim Yegorushkin

Arne said:
Why does this code not compile in GCC 4.x:

And what is the compiler output?
int
main()
{
int a[100];
void *pa = (void *)a;

((char*)pa) += 2;

return 0;
}

Note that the expression

((char*)pa) += 2;

does not produce any effect, since the cast returns an r-value (a
temporary object) which is then added with 2 and destroyed.

If you need to add 2 to pa proper ways of doing so include:

pa = (char*)pa + 2;
((char*&)pa) += 2;
(*(char**)&pa) += 2;
 
A

Arne Schmitz

Invalid lvalue in assignment.
And what is the compiler output?
Note that the expression

((char*)pa) += 2;

does not produce any effect, since the cast returns an r-value (a
temporary object) which is then added with 2 and destroyed.

That does make sense. Although it is interesting, that g++ 3.3 did not even
warn about this.
If you need to add 2 to pa proper ways of doing so include:

pa = (char*)pa + 2;

No, that also does not work, one has to explicitly convert:

pa = (int *)((char *)pa + 2);

Evil, evil stuff. Thank god this is not my code. :)

Arne
 
O

Old Wolf

Arne said:
Maxim said:
Arne said:
Why does this code not compile in GCC 4.x:
int main()
{
int a[100];
void *pa = (void *)a;

Useless cast, remove it.
That does make sense. Although it is interesting, that g++ 3.3 did
not even warn about this.

GCC used to have "cast-as-lvalue" as an extension. If you compiled
with warnings on (-Wall -Wextra -ansi -pedantic), it should tell you.
No, that also does not work, one has to explicitly convert:

Explicit conversions aren't necessary when converting to (void *).
pa = (int *)((char *)pa + 2);

This is likely to have alignment problems (if int has 4-byte alignment
then it can't be aligned correctly both before and after this
operation).

These solutions rely on 'pa' being a 'void *'. If it were an int *,
then we would have undefined behaviour because int* might
be a different size/representation to char* .
 
R

Ron Natalie

Arne said:
((char*)pa) += 2;
The result of the cast does not yield an lvalue. You
can't apply += to it.

Why not either cast to a char* outright if you're going
to try to do byte math (which isn't safe in general).

You could also try
((char*&)pa) += 2;
 
A

Arne Schmitz

Maxim said:
Arne Schmitz wrote:

[]
No, that also does not work, one has to explicitly convert:

If pa is void* this should work.

No, it throws an error. ISO C++ forbids implicit void* conversion, right? (I
said gcc, although I meant g++...)

Arne
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top