-4

Here's some code for example

class A {
  int i;
}

void main()
{
  A a;
}

Is there any possible (probably hackish) way to access a::i in main?

Edit: a::i is supposed to stay private.

McLovin
  • 3,295
  • 7
  • 32
  • 67
  • 4
    Why would you want to do that? Anyway, better post real C++ code. – juanchopanza Dec 29 '15 at 23:20
  • 1
    Just make it public. Anyhow, you could possibly determine the offset of `i` in relation to `a`, thus determine the address of `a.i` from the address of `a`, you'd be a fool to cheat like that though. – Ulrich Eckhardt Dec 29 '15 at 23:23
  • @UlrichEckhardt You'd have a very hard time determining the offset of `i` *a posteriori*. You don't have access to the name so things that you might do are unavailable to you. So you can't call `offsetof` for example. In the specific context of the question we know that `&a` == `&a.i` because the language defines it so for PODs. But if the OP was after some later variable, had custom constructors, virtual functions...shit like that... then he's SOL assuming that he cannot change the definition of `A` to give access as most comments and answers have suggested. – Edward Strange Dec 29 '15 at 23:31
  • 1
    There's no way to give a good answer to this question without understanding what problem the OP is attempting to solve. For example, it's hard to know whether "change `class` to `struct`" is a good answer or a bad joke without knowing that. – David Schwartz Dec 29 '15 at 23:43
  • I said "hackish" so... :) – McLovin Dec 30 '15 at 00:09

4 Answers4

4
*reinterpret_cast<int*>(&a) = 666;

That should do the trick.

Now, technically you're causing UB by using a post reinterpret_cast variable when the types are different. But, i is guaranteed to be at the beginning of A because A is a POD.

This will absolutely not work if there are virtual functions and is not guaranteed to if you have custom constructors.

YOU SHOULD NOT EVER DO ANYTHING REMOTELY LIKE THIS!!

Edward Strange
  • 40,307
  • 7
  • 73
  • 125
2

A very hackish way that I've used for unit testing is (WARNING: only use under adult supervision):

// In your unit test only
#define class struct
#define private public

Put this in a header file that's only used for unit testing!

EDIT: (thanks to @Peter) And only use this for quick and dirty testing - NEVER check this into a repository!

Paul Evans
  • 27,315
  • 3
  • 37
  • 54
  • 1
    not sure whether to report or upvote this, decided to upvote – Untitled123 Dec 29 '15 at 23:33
  • @Untitled123 Hehe - I know the feeling brother! I've often felt like I'm selling my soul to the devil when I do this. But it's proven to be very useful in cases where mocks *etc* would ruin the final design. Either through obfuscation or compromising optimization goals. – Paul Evans Dec 29 '15 at 23:48
  • Redefining language keywords, according to the standard, results in undefined behaviour. – Peter Dec 29 '15 at 23:49
  • @Peter I know, I know - *horrible* hack! But I hope I made that clear in my answer. I've only done this for *very* small-scale short-lived testing and never had anything but good results (*i.e.* flagged real errors). Have *never* checked this type of code into a repository. Edited answer accordingly. – Paul Evans Dec 29 '15 at 23:53
  • I wouldn't use this for unit testing either. If you find yourself tempted to then your class design is probably off. You should be able to test any observable effect with the class's interface, and if you can't then something's off. Maybe on a temporary basis to get legacy code under harness, but that's the only excuse I can think of for doing this. – Edward Strange Dec 30 '15 at 00:00
  • 1
    @CrazyEddie Yes. Totally Agree with you. I've tried to make that perfectly clear. And it's *always* been when I don't have total control over the source code. – Paul Evans Dec 30 '15 at 00:02
1

For sure this is not guaranteed to work, but it will probably work on most platforms:

#include <iostream>

class A {
  int i;

  public:
  A (int j) : i(j) { ; }
};

int awfulGetI(A const& a);

int main()
{
    A a(3);
    int j = awfulGetI(a);
    std::cout << "a.i=" << j << std::endl;
}

// Ugly code that may or may not work here:
struct AA {
  int i;
};

int awfulGetI(A const& a)
{
    struct AA const* p = reinterpret_cast<AA const*>(&a);
    return p->i;
}
David Schwartz
  • 179,497
  • 17
  • 214
  • 278
0

When creating classes, usually the point is to have the encapsulation that they provide (though, of course, you may need to retrieve or mutate the values therein). There is always the possibility of using the memory address as is demonstrated in a couple of answers here, but have you considered creating a public "getter" function in your class that simply returns the value of the variable (since the function itself has access)?

Ex.

class A { 
    // private:
    int i = 7;
    // default value used for illustration purposes.
    // public:
    public int getInt()
      {
         return i;
      } 
     }

int main() {
     A a;
     int x = a.getInt(); // when called, getInt() should return 7 (in this case).
     cout << x; // just to check.
     return 0;
     }
Xellarant
  • 77
  • 1
  • 10