views:

834

answers:

13

Is it ethical to access a class' private members by casting it to a void pointer and then to a struct?

I don't think I have permissions to modify the class that contains the data members that I need to access. I don't want to take a risk accessing the data members in an indirect way if it is not ethical.

EDIT: Had to edit this further... I am pretty sure the class wouldn't be modified, so it's ok to that extent... my only concern is, if the person who coded that class gets to know of this, it might not go down well with him :(.

+4  A: 

Asking the question is answering it.

xtofl
+23  A: 

I'm not sure that "ethics" really come into it. It busts the heck out of encapsulation though.

EDIT: I would almost never accept this if I were performing a code review. You'd have to work really hard to convince me there's no way of designing around the need for this. It's possible you'd succeed, but there'd have to be major warnings all over the place, and rock hard unit tests to make sure that if anything changed to break it, you'd know quickly.

Jon Skeet
that's true, but if you have no other way of doing it, one may have to let go certain concepts?
Shree
Encapsulation isn't really there to protect from abuse. Sometimes, this is the only way to go :-(
Jasper Bekkers
If it is a class of people that you are violating, then there are major ethical concerns :-)
veefu
All 'ethics' really means, when you boil out the pomp and circumstance, is what we've decided should and shouldn't be done. So he's just asking, "hey guys, is it okay to do this if I feel like I need to?"
chaos
Jasper, i would never say doing that casting hax is a "way to go" - unless you wanted to say "way to go to hell" :) probably, the way to go is to ask the author of the class to chance the class or add a access-method :)
Johannes Schaub - litb
@litb, this is by no means something to take lightly; obviously there are steps you should take before performing such hacks.
Jasper Bekkers
+2  A: 

It's ethical, but it's usually lots of dirty code neighbouring with undefined behaviour and unportability. Do it only if you absolutely have to.

sharptooth
People are very liberal (read 'lazy') when determining where the "absolutely have to" line is.
John Dibling
True, and this leads to a series of simple but interesting interview questions which helps in hiring only the people with needed degree of lazyness.
sharptooth
Yes. For both the interviewer and the candidate.
John Dibling
+10  A: 

No. What you are doing is Pure Evil.

John Dibling
Hey, you stole my invisible <sarcasm> tags from http://stackoverflow.com/questions/722350/should-your-opensource-project-attempt-to-mimic-commercial-products.
chaos
I thought the invisible <sarcasm> tags were open source!
John Dibling
+5  A: 

"Never say never". I'm sure somewhere in the universe, there's a situation that will force you to have to do this...

But I certainly would cringe if I had to do it. You truly need get lots of opinions on your situation before pulling the trigger. Can you describe your specific situation and maybe we could see if it makes sense or what better alternatives might exist?

In response to comment/question-- Define "permissions" -- institutional permission? That sounds like not a programming problem, but something to talk to whoever is asserting said permission. Maybe this is more of a political issue than a technical one? Again, I think we need more specifics--even if it was somewhat about the politics of the situation. That may or may not be deemed out of scope for the website, however.

Doug T.
I think I have mentioned that in the question.. I do not have access to that definition, but I need a member defined in that class to compute some value.
Shree
throw away that class and use a class that provides access to the member.
Johannes Schaub - litb
+6  A: 

If you feel the urge to do this, forget casting - just modify the class declaration in the header file:

class A {
  private:
    int x;
};

change that to:

class A {
  public:
    int x;
};

and you are good to go. Well, perhaps "good" is not quite the right word.

anon
why not mention that it violates the ODR. it also goes from non-POD to POD. i imagine chances are better something breaks then. as it stands, one could read your answer as "you can just do ... it will work"
Johannes Schaub - litb
Just remember that while playing Russian roulette, once each so often the bullet fires.
David Rodríguez - dribeas
It only breaks the ODR if the definition of A is in a library. And I wasn't being entirely serious...
anon
Neil, i'm sorry. i've just seen so many answers on SO where they are *really* serious about that. i'll note your nick as the "be-serious candidates". good point about the library though :)
Johannes Schaub - litb
Well if I had access to the header, even then I wouldn't have done this. All I would have had to do is to write another accessor method.
Shree
This relies on unspecified behavior. The best part of your post is the last sentence.
David Thornley
@david That depends - see previous comments. And I did intend the answer to be tongue in cheek.
anon
For what matters, just copy the header and make your code (class/function) a friend of the original class. You will not change anything in the class and the compiler will give you full access...
David Rodríguez - dribeas
If you're going to do this, don't bother copying the header, just wrap it with #define private public #undef private when you include it.
Eclipse
Josh: this is illegal...........
Iraimbilanja: But it works and since this is a hack anyway it is safer than making a copy of a class definition that can go out of date.
James Dean
+1  A: 

Ah, abstraction - you can't live without it and yet it is so painful to deal with sometimes :)

Anyway, ethics aside, what if the "owner" of the class decides to change the internal implementation, or simply reverses the order of the private data members?

Nemanja Trifunovic
Generally only painful to deal with if you screw it up.
John Dibling
@John so true! +1
Neil Williams
+1  A: 

Simple answer: No.

It is not ethical and it will turn into a maintenance nightmare at some point. The internal private members of a library can change and break your code. Developers of the library do not need to know (nor want to) that you are violating the encapsulation.

Classes usually have invariants over their methods that some times will not be documented, but accessing and changing the values from the outside can break those invariants. As an example, if you change the reserved space in a vector for a higher value, the vector will not allocate new space until it has filled the existing and that won't happen before hitting unallocated memory: your application will crash.

If the attribute is private, it is not for you to use it, only for the class itself or the the class' friends that know about the member, how to use it, how not to break it. If the programmer wanted you to change the field, it would be public.

David Rodríguez - dribeas
Accepted... this was why I happened to ask this question... but is there any other way of accessing members? At least I cannot think of any...
Shree
Without more information on the real problem, I cannot tell. But I would think that maybe you want to tackle your problem from another perspective with the information you do have about the class.
David Rodríguez - dribeas
+23  A: 

Let's not consider ethics for a moment. Let's consider the standard.

What you are proposing to do is nonstandard. See section 9.2, clause 12 of the standard. "The order of allocation of nonstatic members separated by an access-specifier is unspecified." Therefore, if you have a class with private members, and a struct with no private members, the standard does not guarantee that the members will be in the same order.

Therefore, if your hack works, it works only by accident, that the compiler writers happened to do it that way. There is no guarantee that it will work on another compiler, a later version of the same compiler, or with different class layouts.

Not to mention that, if you don't have authority to modify the class (say, to provide a simple accessor function), you probably don't have authority to object if any implementation detail in the class changes. (One of the ideas behind public and private is to distinguish what is promised from what is freely changeable.) Therefore, the layout may change, or the member might come to mean something different, or be removed altogether.

Herb Sutter wrote a Guru of the Week column on this issue.

Oh, as far as the ethics go? If you really, really have to do something like this, and you can't get out of it, document it very carefully. If your coding standards have some sort of procedure to flag nonstandard behavior, use them. If not, be very careful to note it in a way it won't be overlooked when something goes wrong.

David Thornley
Liked your opinion :)
Shree
Really nice reference to GoTW. I would upvote again if I could.
David Rodríguez - dribeas
Thank you much... I was just about ready to dig out my copy of the standard and check the allocations clause for guarantees. Very nice detective work.
D.Shawley
" if your hack works, it works only by accident, that the compiler writers happened to do it that way"...on that compilation. Changing to a higher level of optimization on the next compile might make it quit working. I've even seen compilers (DEC) that optimized better if they happen to have more RAM available this compile.
T.E.D.
+3  A: 

I have had this happen to me since there was a very crappy source control system in place where for old versions of the application making changes to header files was pretty much impossible.

If some cases you just need to do a hack.

In the source file from which you need to access the private data member you can put in this as a first line:

#define private public
#define protected public

and access anything you want.

James Dean
I think I should give this a try, but again may not be ethical. But yes, as you said, in some cases it is just impossible to modify some code.
Shree
+1  A: 

The only "ethical" problem is what you are doing to the poor bastard who is going to have to figure out and maintain your code.

Private members are just that. He may, and most likely will, one day change that member. When that happens, you might not even notice as there most likely will still be memory there, just not the member you were expecting. Damn near any nearly impossible thing you can imagine might then start happening when your code is run. How is anybody ever going to be able to debug that?

T.E.D.
+4  A: 

I've just added an entry to my blog that shows how it can be done in a completely conforming way. Here is an example on how you use it for the following class

struct A {
private:
  int member;
};

Just declare a tag name and instantiate a robber like the following example shows (my post shows the implementation of the robber). You can then access that member using a member pointer

struct Amem { typedef int type; };
template class rob<Amem, &A::member>;

int main() {
  A a;
  a.*result<Amem>::ptr = 42; // Doh!
}

But actually, this doesn't show that c++'s access rules aren't reliable. The language rules are designed to protect against accidental mistakes - if you try to rob data of an object, the language by-design does not take long ways to prevent you.


The above is a way to access private and protected members in a conforming way. This one is another way to access protected members in a Standard conforming way. The basic idea is to use a member pointer

std::deque<int> &getAdapted(std::stack<int> &s) {
    struct voyeur : stack<int> 
    { using stack<int>::c; };
    return s.*(&voyeur::c);
}

int main() {
    std::stack<int> s;
    std::deque<int> &adapted = getAdapted(s);
    output(adapted); // print the stack...
}

No casting or type punning involved. It takes a pointer to a protected member of std::stack<int> through a class derived from it where that member name is public, so the compiler allows this. Then it uses it on a std::stack<int> object, which is allowed too.

Johannes Schaub - litb
A: 

I assume that this class is part of project you are working on.

There is one ethical problem here: If in your company you see ownership of code as sacrum. Or worst you are disallowed to modify code that is not yours. Yes You may hurt feeling of person that maintain that class. Or angry him if his salary is related to his code. so best is just to ask him for any help, and few suggestions eg. add getter function or change private to public - all based on your intuition of using that new code.

Hack that you have mention is really bed practice. If cant modify that code and maintainer dont wont to change anything. Consider using adapter design pattern.

przemo_li