Wednesday, July 9, 2014

Read one address and get two different values

This post is about fun with undefined behavior. There are a few different things going on:
  1. We are casting a struct to a int**.
  2. We are modifying the value of a constant private member.
  3. We are modifying the value of a constant variable on the stack.
When we read the address and value of size, the compiler is probably performing optimizations. Instead of reading the value of size, it's probably just replacing it with the literal 3.

Tested with Visual Studio 2012

#include <iostream>

struct PtrHolder
{
    PtrHolder (const int *p) : p (p)
    {
    }

private:
    const int *p ;
};

int main (void)
{
    const int size = 3 ;

    char buffer [size] = {} ;

    PtrHolder ph (&size) ;

    int **pp = reinterpret_cast <int **> (&ph) ;

    std::cout << "*pp: " << *pp << ", pp[0][0]: " << pp[0][0] << "\n" ;
    std::cout << "&size: " << &size << ", size: " << size << "\n" ;

    pp [0] [0] = 2 ;

    std::cout << "*pp: " << *pp << ", pp[0][0]: " << pp[0][0] << "\n" ;
    std::cout << "&size: " << &size << ", size: " << size << "\n" ;

    return 0 ;
}

Output
*pp: 0041FD28, pp[0][0]: 3
&size: 0041FD28, size: 3
*pp: 0041FD28, pp[0][0]: 2
&size: 0041FD28, size: 3

No comments:

Post a Comment