1

Using pointer, I am able to modify the private value of the class in the code below.

Does it violate the C++ concept that private member can only be modified by member or friend functions?

#include<iostream>
using namespace std;

class demo
{
        private: int info;

        public:
                 demo()
                 {
                         info=10;
                 }

                 void print_info()
                 {
                       cout<<info;
                 }
};

int main()
{

     demo ob;
     int* ptr=(int*)&ob;

     *ptr=20;

     ob.print_info();

     return 0;
}
3
  • 1
    isn't reinterpreting pointers like that a recipe for undefined behavior? Aug 9, 2013 at 11:12
  • Using reflection, you can modify private members in languages like C# and Java. In both cases, you are going out of your way to poke at the data structures. Like Bart said, access modifiers are meant to protect you from accidents, nothing more. After all, it's all your process' memory, and what your process does with it is really nobody else's concern.
    – user
    Aug 9, 2013 at 11:33
  • 1
    But the C# variant is a bit different since low trust code can't use it. C++ on the other hand only knows fully trusted code. Aug 9, 2013 at 11:36

6 Answers 6

11

The C++ mechanism of public, protected and private members is meant to protect you from accidents, not from malicious intent.

Re-interpreting a pointer as if it points at something else (like you do with int* ptr=(int*)&ob) counts as 'malicious intent' and usually means that you are stepping beyond the C++ language. What happens is entirely up to the compiler and it does not have to be consistent in what it does.


Note that there are other ways to expose private data, for example:

class demo
{
    private: int info;

    public:
             demo()
             {
                     info=10;
             }

             int* expose_info()
             {
                    return &info;
             }
};

This is entirely legal in C++ (although usually a bad idea). The public/protected/private mechanism works only on names (so the name info is inaccessible for outsiders), but if you can get your hands on a pointer/reference to a private member, you have full access to that member.

3

Access descriptors in C++ are a static mechanism. Compliance is checked at compile time by the compiler, and no memory of the privacy level of methods or attributes is retained at run time, nor are any checks performed by then.

By using a C-style cast you are completely circumventing C++ static checks and all bets are off.

2
  • 2
    I would add that using any kind of cast (c-style or c++ style) tells the compiler that you, the programmer, are smarter than the compiler. You are telling the compiler "trust me, I know what I am doing." Umm, yeah.
    – Bill Door
    Aug 9, 2013 at 16:22
  • 1
    True. By singling out the C-style cast I just meant that it's a particularly strong type of cast... you are basically shouting "I know what I am doing!" :)
    – UncleZeiv
    Aug 9, 2013 at 17:56
2

The exact posted code has has defined behavior under c++11, since demo is a standard-layout class and info (the data member) is accessed as a compatible type, but it is bad style.

Standard-layout class must:

  • Have the same access control for all data members
  • Have no virtual functions
  • Only inherit from standard-layout classes
  • At most one class in its class hierarchy has data members
  • Has no data members with the same type as any in the class hierarchy

This text is simplified from 9.7 of the draft standard. In my terminology, class hierarchy includes the class itself, and data members only covers non-static data members.

Accessing the data member with an incompatible type would cause undefined behavior, as always. For instance short is undefined, but char and int is defined.

In short, such access is defined if the class is standard-layout . So be VERY careful. You can check if a type is standard-layout with std::is_standard_layout

0

This has been happening accidentally for years via buffer overflows, bad aliases, and other pointer errors. You write memory past the bounds of an array, and viola! you are corrupting the (possibly private) memory in another object. You are using a pointer that has been de-allocated elsewhere, then another process creates an object at that address and viola!, you are corrupting memory. The accessibility features of C++ are for writing contracts and separating concerns in your design for your users. Just like in C# and JAVA, it doesn't prevent anyone--most likely yourself accidentally-- from misusing pointers.

On a side note, you can also use memcpy to copy one class to another using the same exact idea. You should never actually do that in production code, but it can easily be done.

0

In 'The C++ Programming Language' the author Bjarne Stroustrup writes:

The protection of private data relies on restriction of the use of the class member names. It can therefore be circumvented by address manipulation and explicit type conversion. But this, of course, is cheating, C++ protects against accident rather than deliberate circumvention (fraud). Only hardware can offer perfect protection against malicious use of a general-purpose language, and even that is hard to do in realistic systems.

It can be said that manipulation is legal but it is a bad practice to preform such manipulations on private member variables.

0

There are very few guarantees about the layout of instance variables in C++. For example, the presence of the "private" or "public" keyword means that the C guarantee about members have ascending memory addresses is gone. So if you had another member int info2; there would be no guarantee that your code works. I'm not sure if there is any guarantee for the code as it is.

According to user2229152 your code will work. How sure are you that user2229152 is correct? Would you bet on it? It may work today and stop working when you switch to a newer compiler version. Or compile for a different processor. Do you feel lucky?

Not the answer you're looking for? Browse other questions tagged or ask your own question.