Re: casting A* to A& ?

Tech-Archive recommends: Speed Up your PC by fixing your registry

From: Sigurd Stenersen (sigurds_at_utvikling.com)
Date: 10/08/04


Date: Fri, 8 Oct 2004 14:09:17 +0200

Agoston Bejo wrote:
> What happens exactly when I do the following:
>
> struct A {
> int i;
> string j;
> A() {}
> };
>
> void f(A& a) {
> cout << a.i << endl;
> }
>
> int _tmain(int argc, _TCHAR* argv[])
> {
> A a;
> a.i = 6;
> A* pa = &a;
> f((A&)pa); // CRITICAL POINT
> f(*pa); // works as expected
> return 0;
> }
>
>
> How come that this is legal, anyway?

You can cast something at an address to something else at the same address.
Try doing the same cast with a constant and you'll see that that is not
allowed.

> Lately I've seen some people expect that (A&)pa be equivalent to *pa,
> which is not according to the example above.

No, it is not. *pa is a reference to whatever pa is pointing to, tho. So
    f(*pa);
is perfectly fine.

> (The output for
> f((A&)pa) looks like some integer, but surely not 6 as should be if
> it meant f(*pa).)

The integer is equal to the address of a.

What actually happens is you're telling the compiler that "look here, pa is
not a pointer it's a struct of type A". That is in fact wrong, but because
you're telling the compiler that you know better it let's you do it. And
you're lucky, because the size of pa happens to be the same as the size of
an A instance. As it happens, the value of p overlaps A::i when you do the
cast.

Thus, you only get bogus results in this simple example, in reality you'd
usually get an access violation or some other hardtofind bug.

In other words, when you use a typecast, you're telling the compiler that
you know what you're doing. And that's a very silly thing to tell the
compiler if you don't know what you're doing...

(Yes, references are implemented the same way as pointers. But they have
different semantics.)

-- 
Sigurd
http://utvikling.com


Relevant Pages

  • Re: HardBound and SoftBound (was "The State of Software")
    ... I will explain to you one last time that the problem is not whether a compiler can generate checks for all buffer overflows. ... By the way, in the last example of such code that I saw, it had been changed to use the address of the struct, not of the first element of the struct: ... to take address of struct rather than address of first element. ... such tricks are used to create a pointer which is then passed on. ...
    (comp.arch)
  • Re: problem with memcpy and pointers/arrays confusion - again
    ... this second method is known as an explicit conversion, or cast. ... The cast, in effect, tells the compiler: ... the malloc function. ... function taking a size_t as a parameter and returning a void pointer (i.e. ...
    (comp.lang.c)
  • Re: Why the compiler applies sign extension to unsigned data?
    ... I want the value of p to be made unsigned *before* the cast. ... want the cast to generate a sign extension. ... ULONG_PTR is ULONG and casting the pointer to ULONG_PTR first is the ... on the compiler and on the knowledge of the size of the ptr variable, ...
    (microsoft.public.development.device.drivers)
  • Re: pointers to struct members
    ... >I just compiled a program that uses linked lists (needed it as an homework ... The compiler diagnostic is not the problem. ... remove_key requires a pointer to pointer to struct as its first ...
    (comp.lang.c)
  • Re: Can I Trust Pointer Arithmetic In Re-Allocated Memory?
    ... If your compiler ... it works with a cast. ... Pointer arithmetic, as you probably know, is scaled by ... not sure about concerning realloc(). ...
    (comp.lang.c)