Data corruption in protected access in c++ - c++

Variables "protected" are prone to be malicious changed by derived class?
Should I use "private" in base class variables instead of "protected"?

If you're worried about 'malicious' modifications, then even marking data as private: will not help.
The C++ access specifiers are only useful for code that's essentially playing by the rules.
Marking a member as private will prevent normal users of your class from messing with them. However, even non-malicious code that has bugs can corrupt those members. Overruns, buggy pointer arithmetic or improper use of casts lets a C++ programmer cause these problems.

"Malicious" access can't be prevented in C++, because you can always get around the compiler restrictions somehow. If you're worried about "accidental" changes, go ahead and make it private.

Well, protected members do get inherited. If you don't want that to happen, make them private.

Take a look at: http://www.parashift.com/c++-faq-lite/private-inheritance.html#faq-24.5
You probably want private.

In general, if you're contemplating declaring a private variable, you should step back and ask yourself why are you even publishing the declaration in the header file?
instead of exposing your member variables for all the world to see in foo.h:
class foo {
private:
int please_dont_modify_me;
double pretend_you_dont_see_this_declaration;
char dont_look_at_this [128];
public:
....
};
just use an incomplete private type, that is not defined:
class foo {
struct foo_privates & mine; // incomplete type
public:
...
};
then in foo.cpp ONLY:
struct foo_privates {
int i;
double d;
char str[128];
};
Of course, the constructor for foo has to allocate the separate object and the destructor has to destroy it.

Related

Differences between these two PIMPL approaches

So when trying to get in touch with the PIMPL idiom one finds two common ways of doing it:
Using forward declaration outside a class:
class PimplClass;
class VisibleClass
{
private:
PimplClass* d_ptr;
};
Using forward declaration inside a class:
// *.hpp
class VisibleClass
{
private:
struct PimplClass;
PimplClass* d_ptr;
};
// *.cpp file:
struct VisibleClass::PimplClass
{
int x;
};
Two questions here:
To be honest I have no idea why the second one works. I mean the expression struct PimplClass I only do know from forward declaration but not within a class. Can someone please explain this to me?
Which solution to use? Where are the advantages or is it jsut a matter of taste?
It's a forward-declaration too, but PimplClass is scoped inside VisibleClass.
That second solution has the advantage of not dumping an internal type into the global namespace. Keeping PimplClass scoped inside VisibleClass makes complete sense.
In both cases, the Pimpl idiom should generally use a std::unique_ptr to tie the lifetimes of the interface and the Impl together, rather than a raw owning pointer.
You may do a forward declaration within class scope. So the second example is absolutely correct.
The main plus of second example is that your PimplClass can't be accessed from anywhere but from VisibleClass because it is declared (forward-declared) inside it's private section.

what does one sacrifice with this pimpl alternative?

I have, unfortunately, used Qt a lot (it purports to be many things that it is not) and since Qt uses the pimpl idiom extensively, I've gotten a lot of experience with the pimpl pattern as well and learned I don't like it. One alternative I like to use is:
// .hpp file
struct A
{
private:
struct B;
int a{};
};
// .cpp file
struct A::B
{
// replaces a private member function
static void f(A& a)
{
++a.a;
}
};
But what is sacrificed using this approach instead of using private function members or pimpl? Performance, binary compatibility? With pimpl, we know that it is performance, because of 1 level of added indirection.
Well, for one - this won't work if struct B needs to be a class template that takes arbitrary type parameters.
If A::B only contains static methods/data, there is no point in exposing that at all in the header. You can much simpler only implement those function in the .cpp file, without making them part of to the class.
// .hpp file
struct A
{
};
// .cpp file
void f(A& a)
{
// some function
// Might be called from the implementation of methods of `A`
}
So there is not really a reason to have a nested class in the first place.
On the other hand, if you do have non-static data/... in A::B that needs to be associated with instances of A (the situation where the pimpl idiom is used), then you somehow need to associate a A::B instance with every instance of A.
A straight forward way to do this would be to save a pointer to a A::B in each A. This is the pimpl idiom.
The idea of pimpl is to store data in each instance of A without making the internal structure of that data part of A's public interface.
Your code doesn't do that, so it doesn't replace pimpl.
In short, your code is a way to hide helper functions which are implementation details. pimpl does that and ALSO hides helper data which are implementation details.

Static library: hiding private members from header file

I wish to compile part of my code as a static library to include in other project. Of course I'll have to distribute the compiled library and an header file containing the class declaration and the public members, but I don't know if it's possible to move all private members and declarations to a place different than the header file.
Example:
In the project.h file:
class MyClass
{
public:
MyClass();
void Give_me_an_input(int);
int Get_your_output();
private:
int a, b;
int MySecretAlgorithm();
};
In the .cpp file:
MyClass::MyClass()
{
a = 1;
b = 0;
}
void MyClass::Give_me_an_input(int c)
{
b = c;
}
int MyClass::Get_your_output()
{
return MySecretAlgorithm();
}
int MyClass::MySecretAlgorithm()
{
return (a + b);
}
Is there a way to move all private members int a, b; and int MySecretAlgorithm(); to a place different than the header file?
The pointer to implementation idiom can be used in such a scenario, commonly referred to as pimpl.
The basic idea is to take the implementation details out of the declaration
and simply have an opaque pointer to the implementation details.
std::unique_ptr is used in the the following example; but you could of course just use normal pointers.
// my_class declaration unit.
class my_class {
private:
class impl;
unique_ptr<impl> pimpl;
public:
};
// my_class implementation unit
class my_class::impl {
int whatever;
int whenever;
};
my_class::my_class(): pimpl( new impl )
{
}
Over the years I've seen some hacks to do this, but I don't think they are worth it. If your library is reasonably 'chunky' (ie: no method is being called a billion times a microsecond); and you can re-write chunks of your code...
You might consider making all the public stuff an abstract class (all virtual = 0) and then deriving your concrete classes from it.
Down sides of this:
- All your public calls become virtual (some optimizations can bypass this, but not often).
- You can't 'new up' your classes anymore, you'll need to implement a factory pattern.
The problem with any of the other hacks I'm familiar with is that they basically declare the methods in one set of headers, and then redeclare the same things with the 'real' implementation in private headers - depending on the linker to match up the names. A couple problems here are:
Maintaining this mess sucks. You can't use an #ifdef because it sounds like you want to physically hide your implementation. So you have dual maintaining, or a build step that generates your public headers.
Can only be used via pointer. You have to play games making constructors private and still have a factory because the compiler won't generate structs of the right size if you let the client gen it by value (or even with new).
Finally, I once saw a hack where the programmer tried to declare a byte array in the private area of the 'public' class so that the client code could still declare by value or 'new' it themselves. This suffers all the previous problems, plus you probably don't want to have to 'know' the size of the structs since they depend on packing and alignment. Your 'build step' would more or less have to have a runtime component that used sizeof() - and now you have a versioning problem if you want to change the size of the struct/class.

hiding inner class implementation using namespace

I am developing a library and a would like to provide my users a public interface separate from the real implementation that is hidden in a namespace. This way, I could change only the class HiddenQueue without changing myQueue that will be exposed to users only.
If I put the C++ code of HiddenQueue in the myQueue.cpp file the compiler complains saying _innerQueue has incomplete type. I thought that the linker was able to resolve this. What I am doing wrong here?
// myQueue.h
namespace inner{
class HiddenQueue;
};
class myQueue{
public:
myQueue();
);
private:
inner::HiddenQueue _innerQueue;
};
///////////////////////////
// myQueue.cpp
namespace inner{
class HiddenQueue{};
};
The compiler needs to know the exact memory layout of an object by looking at the header file it's defined in.
Your code says that class MyQueue has a member of type InnerQueue, which will be part of the memory layout of MyQueue objects. Therefore, to deduce the memory layout of MyQueue it needs to know the memory layout of InnerQueue. Which it does not, because you say "oh well, it's defined elsewhere".
What you are trying to do is closely related to "the PIMPL idiom"/"compiler firewall" technique.
To solve the problem, you must either include HiddenQueue.h in your header or declare _innerqueue as a pointer:
class myQueue {
public:
myQueue();
private:
inner::HiddenQueue* _pinnerQueue;
};
Using a pointer is possible because a pointer has a known memory size (dependent on your target architecture), therefore the compiler doesn't need to see the full declaration of HiddenQueue.
To be able to make a member of a class, you need to have a definition for it and not only a declaration. (A declaration is enough for a pointer or a reference to the class).
You need to provide pointer to _innetQueue rather then the object itself:
std::auto_ptr<inner::HiddenQueue> _innerQueue;
Search form pimpl ideom or d-pointer

C++ Is private really private?

I was trying out the validity of private access specifier in C++. Here goes:
Interface:
// class_A.h
class A
{
public:
void printX();
private:
void actualPrintX();
int x;
};
Implementation:
// class_A.cpp
void A::printX()
{
actualPrintX();
}
void A::actualPrintX()
{
std::cout << x:
}
I built this in to a static library (.a/.lib). We now have a class_A.h and classA.a (or classA.lib) pair. I edited class_A.h and removed the private: from it.
Now in another classTester.cpp:
#include "class_A.h" // the newly edited header
int main()
{
A a;
a.x = 12; // both G++ and VC++ allowed this!
a.printX(); // allowed, as expected
a.actualPrintX(); // allowed by G++, VC++ gave a unresolved linker error
return 0;
}
I know that after tampering a library's header all bets are off (I mean, system integrity, etc.) Albeit the method being hacky, is this really allowed? Is there a way to block this? Or am I doing something wrong here?
private is not a security mechanism. It's a way of communicating intents and hiding information that other parts of your program do not need to know about, thus reducing overall complexity.
Having two different header files is not standards compliant, so technically you're entering undefined behaviour territory, but practically, as you've found, most compilers won't care.
You've strayed beyond what's allowed in C++, so what you're doing isn't allowed - but of course it may work on some compilers in some situations.
Specifically, you're violating the One Definition Rule.
This article by Herb Sutter explains it quite nicely - it also provides a legal and portable way of circumventing the access specifier system.
No. The private access control is there to stop YOU from doing stupid things, not as a security mechanism to stop others accessing your data or functions. There are many, many ways of getting around it.
I tried. This is an nm of a program I wrote having a class Test with one private method and a public one.
0000000100000dcc T __ZN4Test3barEv
0000000100000daa T __ZN4Test3fooEv
As you can see, the signature is exactly the same. The linker has absolutely nothing to distinguish a private method from a public one.
I agree with most of the other answers.
However, I'd like to point out that it is perfectly acceptable for a compiler to physically arrange the members differently when you remove that private. If it works, that is luck. You can't count on it. If both sides aren't using the same declaration, they aren't really using the same class.
There is no A::actualPrintX implementation anywhere. That is your linker error.
Since noone has mentioned a way to block this... One possible way to block access to private members, is to declare them as a separate internal type not visible outside the file. Of course, if you want to provide explicit access to this internal, you would then have to provide the internal declaration. That's also commonly done using an internal header containing that type.
Note: You'll have to keep track of allocating/freeing that internal object in this example. There are other ways of doing it that don't require this.
// class_A.h
class A {
public:
void printX();
private:
void *Private;
};
// class_A.cpp
class A_private {
void actualPrintX();
int x;
};
void A::printX() {
reinterpret_cast<A_private *>(Private)->actualPrintX();
}
void A_private::actualPrintX() {
std::cout << x:
}
In most cases you don't even have to edit header file to make private members public. You can do this with preprocesor. Something like this:
//"classWithPrivateMembers.hpp"
class C
{
private: //this is crucial for this method to work
static int m;
};
int C::m = 12;
and then, this will work:
#define private public
#include "classWithPrivateMembers.hpp"
#undef private
int main()
{
C::m = 34; // it works!
}
Bear in mind also that when you change a member variable's access, the compiler may place it at a different offset within the class object. The standard allows compilers a fair amount of freedom in rearranging members (at least within the same access level, I think).