Why is 'this' not volatile? - c++

Having spent the last few days debugging a multi-threading where one thread was deleting an object still in use by another I realised that the issue would have been far easier and quicker to diagnose if I could have made 'this' volatile. It would have changed the crash dump on the system (Symbian OS) to something far more informative.
So, is there any reason why it cannot be, or shouldn't be?
Edit:
So there really is no safe way to prevent or check for this scenario. Would it be correct to say that one solution to the accessing of stale class pointers is to have a global variable that holds the pointer, and any functions that are called should be statics that use the global variable as a replacement for 'this'?
static TAny* gGlobalPointer = NULL;
#define Harness static_cast<CSomeClass*>(gGlobalPointer);
class CSomeClass : public CBase
{
public:
static void DoSomething();
private:
int iMember;
};
void CSomeClass::DoSomething()
{
if (!Harness)
{
return;
}
Harness->iMember = 0;
}
So if another thread deleted and NULLed the global pointer it would be caught immediately.
One issue I think with this is that if the compiler cached the value of Harness instead of checking it each time it's used.

this is not a variable, but a constant. You can change the object referenced by this, but you can't change the value of this. Because constants never change, there is no need to mark them as volatile.

It wouldn't help: making a variable volatile means that the compiler will make sure it reads its value from memory each time it's accessed, but the value of this doesn't change, even if, from a different context or the same, you delete the object it's pointing at.

It can be. Just declare the member function as volatile.
struct a
{
void foo() volatile {}
};

volatile wouldn't help you.
It would make the access to a variable volatile, but won't wait for any method to complete.
use smart pointers.
shared_ptr
There's also an version in std in newer c++ versions.

If the object is being read whilst being deleted that is a clear memory error and has nothing to do with volatile.
volatile is intended to stop the compiler from "remembering" the value of a variable in memory that may be changed by a different thread, i.e. prevent the compiler from optimising.
e.g. if your class has a pointer member p and your method is accessing:
p->a;
p->b;
etc. and p is volatile within "this" so p->b could be accessing a different object than it was when it did p->a
If p has been destroyed though as "this" was deleted then volatile will not come to your rescue. Presumably you think it will be "nulled" but it won't be.
Incidentally it is also a pretty sound rule that if your destructor locks a mutex in order to protect another thread using the same object, you have an issue. Your destructor may lock due to it removing its own presence from an external object that needs synchronous activity, but not to protect its own members.

Related

What's better to use and why?

class MyClass {
private:
unsigned int currentTimeMS;
public:
void update() {
currentTimeMS = getTimeMS();
// ...
}
};
class MyClass {
public:
void update() {
unsigned int currentTimeMS = getTimeMS();
// ...
}
};
update() calls in main game loop so in the second case we get a lot of allocation operations (unsigned int currentTimeMS). In the first case we get only one allocate and use that allocated variable before.
Which of this code better to use and why?
I recommend the second variant because it is stateless and the scope of the variable is smaller. Use the first one only if you really experience a performance issue, which I consider unlikely.
If you do not modify the variable value later, you should also consider to make it const in order to express this intent in your code and to give the compiler additional optimization options.
It depends upon your needs. If currentTimeMS is needed only temporarily in the update(), then surely declare it there. (in your case, #option2)
But if it's value is needed for the instance of the class (i.e. being used in some other method), then you should declare it as a field (in your case, #option1).
In the first example, you are saving the state of this class object. In the second one, you're not, so the currentTime will be lost the instant update() is called.
It is really up to you to decide which one you need.
The first case is defining a member variable the second a local variable. Basic class stuff. A private member variable is available to any function (method) in that class. a local variable is only available in the function in which it is declared.
Which of this code better to use and why?
First and foremost, the cited code is at best a tiny micro-optimization. Don't worry about such things unless you have to.
In fact, this is most likely a disoptimization. Sometimes automatic variables are allocated on the stack. Stack allocation is extremely fast (and even free sometimes). There is no need to worry. Other times, the compiler may place a small automatic variable such the unsigned int used here in a register. There's no allocation whatsoever.
Compare that to making the variable a data member of the class, and solely for the purpose of avoiding that allocation. Accessing that variable involves going through the this pointer. Pointer dereference has a cost, potentially well beyond that of adding an offset to a pointer. The dereference might result in a cache miss. Even worse, this dereferencing may well be performed every time the variable is referenced.
That said, sometimes it is better to create data members solely for the purpose of avoiding automatic variables in various member functions. Large arrays declared as local automatic variables might well result in stack overflow. Note, however, that making double big_array[2000][2000] a data member of MyClass will most likely make it impossible to have a variable of type MyClass be declared as a local automatic variable in some function.
The standard solution to the problems created by placing large arrays on the stack is to instead allocate them on the heap. This leads to another place where creating a data member to avoid a local variable can be beneficial. While stack allocation is extremely fast, heap allocation (e.g., new) is quite slow. A member function that is called repeatedly may benefit by making the automatic variable std::unique_ptr<double> big_array = std::make_unique<double>(2000*2000) a data member of MyClass.
Note that neither of the above applies to the sample code in the question. Note also that the last concern (making an heap-allocated variable a data member so as to avoid repeated allocations and deallocations) means that the code has to go through the this pointer to access that memory. In tight code, I've sometimes been forced to create a local automatic pointer variable such as double* local_pointer = this->some_pointer_member to avoid repeated traversals through this.

Double-checked Locking for Shared Pointers

Disclaimer: I come from a Java background, and, as such, I have no clue on how a lot of the internals of C++ (and associated libraries) work.
I have read enough to know that double-checked locking is evil, and a correct and safe implementation of a singleton pattern requires the appropriate tools.
I believe the following code may be unsafe, subject to compiler reordering and assignment of uninitialized objects, but I am not sure if I am missing something that I do not understand about the language.
typedef boost::shared_ptr<A> APtr;
APtr g_a;
boost::mutex g_a_mutex;
const APtr& A::instance()
{
if (!g_a)
{
boost::mutex::scoped_lock lock(g_a_mutex);
if (!g_a)
{
g_a = boost::make_shared<A>();
}
}
return g_a;
}
I believe the actual code is compiled under C++03.
Is this implementation unsafe? If so, how?
Yes, the double-checked locking pattern is unsafe in archaic languages. I can't do any better than the explanation in What's wrong with this fix for double checked locking?:
The problem apparently is the line assigning instance -- the compiler is free to allocate the object and then assign the pointer to it, OR to set the pointer to where it will be allocated, then allocate it.
If you were using C++11 std::shared_ptr, you could use atomic_load and atomic_store on the shared pointer object, which are guaranteed to compose correctly with each other and with mutexes; but if you're using C++11 you may as well just use a dynamically-initialized static variable, which is guaranteed to be thread-safe.
All of this is absolutelty unneccesary in modern C++. Singleton code should be as simple as this for anybody but dinosaurs:
A& A::instance() {
static A a;
return a;
}
100% thread safe in C++11 and up.
However, I have a mandatory statement to make: Singletons are evil antipattern and should be banned forever.
On thread safety of original code
Yes, provided code is unsafe. Since the reading is done outside the mutex, it is totally possible that the modifications to g_a itself would be visible, but not that modifications to the object g_a is pointing to. As a result, the thread will bypass mutex locking and return a pointer to non-constructed object.

Copy static class member to local variable for optimization

While browsing open source code (from OpenCV), I came across the following type of code inside a method:
// copy class member to local variable for optimization
int foo = _foo; //where _foo is a class member
for (...) //a heavy loop that makes use of foo
From another question on SO I've concluded that the answer to whether or not this actually needs to be done or is done automatically by the compiler may be compiler/setting dependent.
My question is if it would make any difference if _foo were a static class member? Would there still be a point in this manual optimization, or is accessing a static class member no more 'expensive' than accessing a local variable?
P.S. - I'm asking out of curiosity, not to solve a specific problem.
Accessing a property means de-referencing the object, in order to access it.
As the property may change during the execution (read threads), the compiler will read the value from memory each time the value is accessed.
Using a local variable will allow the compiler to use a register for the value, as it can safely assume the value won't change from the outside. This way, the value is read only once from memory.
About your question concerning the static member, it's the same, as it can also be changed by another thread, for instance. The compiler will also need to read the value each time from memory.
I think a local variable is more likely to participate in some optimization, precisely because it is local to the function: this fact can be used by the compiler, for example if it sees that nobody modifies the local variable, then the compiler may load it once, and use it in every iteration.
In case of member data, the compiler may have to work more to conclude that nobody modifies the member. Think about multi-threaded application, and note that the memory model in C++11 is multi-threaded, which means some other thread might modify the member, so the compiler may not conclude that nobody modifies it, in consequence it has to emit code for load member for every expression which uses it, possibly multiple times in a single iteration, in order to work with the updated value of the member.
In this example the the _foo will be copied into new local variable. so both cases the same.
Statis values are like any other variable. its just stored in different memory segment dedicated for static memory.
Reading a static class member is effectively like reading a global variable. They both have a fixed address. Reading a non-static one means first reading the this-pointer, adding an offset to the result and then reading that address. In other words, reading a non-static one requires more steps and memory accesses.

Do I ever have to check for a pointer validity on this method?

class A
{
private:
A(){};
~A(){};
public:
static A* GetInstance( void )
{
static A obj;
return& obj;
}
};
I was supposing if something bad happens would only happen at the first time, since the class constructor is only initialized the first time a call to GetInstance happens, I don't know the great depths of C++ and I do not trust C++, so when I need a pointer to this class that will be used many times in a function I'm currently doing:
A* ptr = A::GetInstance();
if( ptr )
{
Checking for the pointer validity, I believe that the method returns the address where the value of obj is stored so that ptr will point to it, which I guess it can't fail.
Please observe that I'm not talking about a small application, I'm currently developing on a 500,000+ lines MMO server application that handles thousand of clients and has to stay opened for weeks without crashing, defensive programming is the least minimum required. Is it for sure, 100% safe to use ptr without checking its validity?
There is certainly no way that that function will ever return a null pointer, so there's no point checking for that. It might make more sense to return a reference, to make it clear that it won't be null.
However, there's no guarantee that the function will always return a pointer to a valid object. If it's called from the destructor of a static object, then obj might already have been destroyed. This is one reason why globally accessible objects are a very bad idea, whether or not you wrap them up in the Singleton anti-pattern like this.
The function will always return a pointer to an object that exists. The only danger is if the object itself is invalid, and this should have been indicated by a throw from the object constructor. In your case you do not catch an exception from the constructor so the program should halt in that case, otherwise it should be good to go.
Checking for NULL is pointless because you always return a valid address.
Adding a check for the pointer is unlikely to cause significant performance degradation but should be unnecessary. Add it if it will make you feel better. However, I would be more concerned about buffer overflows, memory leaks and other more likely issues than whether the static keyword is implemented by the compiler correctly.

passing HBuf to function

i am passing HBuf to function
but it crashes i don't know whether i am following right way or not
//case 1:
HBufC8* iBuffer2 = HBufC8::NewL(1000 );
TPtr8 bufferPtr( iBuffer2->Des() );
//assigning value to HBuf code
StartParsingL(iBuffer2);
StartParsingL(HBufC8* aHBufPtr)
{
iBuffer = HBufC8::NewL(aHBufPtr->Length());//it crashes here
bufferPtr.Copy(aHBufPtr->Des());//also here
}
Not answering your question (as there isn't really enough information). I would recommend using an RBuf instead of a HBuf as they are the recommended heap buffer descriptor going forward, and a bit easier to use.
In the Symbian coding convention, "i" prefixed variables are member variables.
In your snippet you have it as a local declaration. It could be that you just put in the type for clarity of the snippet, but if you've declared it both as a member variable and as a local declaration, that could explain plenty of crashes :-)
You should have:
class C....: public CBase?....
{
private:
HBufC8* iBuffer2;
};
...
void C...::ConstructL()
{
...
iBuffer2 = HBufC8::NewL(1000);
...
}
This code does not directly show the reason for crashing. Please post actual snippets next time.
Also, when posting about a crash, it is good to know how it is crashing. I assume it is a KERN-EXEC 3 panic. But please be explicit about it yourself.
I guess the aHBufPtr passed to StartParsingL is either zero or otherwise does not point to a valid HBuf8 object. That would be the immediate reason for the crash. Why it is not a valid pointer is not visible in the code, but one reason could be shadowing a member variable with a local variable as suspected by #Will.
Some further points, not related to crash here but Symbian C++ in general:
When passing descriptors around, you should use the most general read-only TDesC or TDesC8 type references or read-write TDes or TDes8 type references. Use HBufC or HBufC8 pointers only if you are transferring ownership to the callee.
In this snippet:
bufferPtr.Copy(aHBufPtr->Des());
Copy accepts a TDesC& so you do not need to call Des:
bufferPtr.Copy(*aHBufPtr);
Though if you just want to copy a descriptor, you could use any of the descriptor Alloc functions such as AllocL.