C++ - Transactional memory: exact meaning of atomic_commit? - c++

Context:
I was reading the Transactional memory reference.
Some info are really unclear to me.
I run the code below in godbolt and I have a sense of what should happen but I want some confirmation or explanation of what is really expected to happen, not what I think should happen.
In the atomic_commit case:
If an exception is thrown, the transaction is committed normally.
That line raises some questions:
auto f() -> std::optional<int> {
static int i = 0;
std::optional<int> p;
atomic_commit {
//some memory ops happen here
++i;
throw std::runtime_error("I decide to fail here, for some reason");
p = i;
return p; // commit transaction
}
return std::nullopt;
}
int main() {
for (int retries = 0 ; retries < 10 ; ++retries) {
try {
auto r = f();
if (r) {
std::cout << r.value() << std::endl;
} else {
std::cout << "nope" << std::endl;
}
} catch (...) {
//handle the exception and maybe retry.
}
}
}
Question:
What happens exactly to the already registered data ? Is it taken back?
If two threads try to write at the same address, and the first one
failed to do so, what happens to the second? is the data corrupted?
In the case no exception is thrown, and two threads try to write in the same
address, what happens exactly?
As an added info, I mostly use the latest gcc.
Other thoughts:
On the other hand, the atomic_cancel seems to have an interesting behavior:
the values of all memory locations in the program that were modified by side effects of the operations of the atomic block are restored to the values they had at the time the start of the atomic block was executed, and the exception continues stack unwinding as usual
That would mean that all the data is copied first (may be faster than a lock).
It is the most natural behavior to me, except for the part that calling std::abort is quite rude.
But it doesn't matter, it is not always implemented anyway(gcc..).
Thanks

Related

How Can this == nullptr Ever be true Without Invoking Undefined Behavior? [duplicate]

Does it ever make sense to check if this is null?
Say I have a class with a method; inside that method, I check this == NULL, and if it is, return an error code.
If this is null, then that means the object is deleted. Is the method even able to return anything?
Update: I forgot to mention that the method can be called from multiple threads and it may cause the object to be deleted while another thread is inside the method.
Does it ever make sense to check for this==null? I found this while doing a code review.
In standard C++, it does not, because any call on a null pointer is already undefined behavior, so any code relying on such checks is non-standard (there's no guarantee that the check will even be executed).
Note that this holds true for non-virtual functions as well.
Some implementations permit this==0, however, and consequently libraries written specifically for those implementations will sometimes use it as a hack. A good example of such a pair is VC++ and MFC - I don't recall the exact code, but I distinctly remember seeing if (this == NULL) checks in MFC source code somewhere.
It may also be there as a debugging aid, because at some point in the past this code was hit with this==0 because of a mistake in the caller, so a check was inserted to catch future instances of that. An assert would make more sense for such things, though.
If this == null then that means the object is deleted.
No, it doesn't mean that. It means that a method was called on a null pointer, or on a reference obtained from a null pointer (though obtaining such a reference is already U.B.). This has nothing to do with delete, and does not require any objects of this type to have ever existed.
Your note about threads is worrisome. I'm pretty sure you have a race condition that can lead to a crash. If a thread deletes an object and zeros the pointer, another thread could make a call through that pointer between those two operations, leading to this being non-null and also not valid, resulting in a crash. Similarly, if a thread calls a method while another thread is in the middle of creating the object, you may also get a crash.
Short answer, you really need to use a mutex or something to synchonize access to this variable. You need to ensure that this is never null or you're going to have problems.
I know that this is old but I feel like now that we're dealing with C++11-17 somebody should mention lambdas. If you capture this into a lambda that is going to be called asynchronously at a later point in time, it is possible that your "this" object gets destroyed before that lambda is invoked.
i.e passing it as a callback to some time-expensive function that is run from a separate thread or just asynchronously in general
EDIT: Just to be clear, the question was "Does it ever make sense to check if this is null" I am merely offering a scenario where it does make sense that might become more prevalent with the wider use of modern C++.
Contrived example:
This code is completely runable. To see unsafe behavior just comment out the call to safe behavior and uncomment the unsafe behavior call.
#include <memory>
#include <functional>
#include <iostream>
#include <future>
class SomeAPI
{
public:
SomeAPI() = default;
void DoWork(std::function<void(int)> cb)
{
DoAsync(cb);
}
private:
void DoAsync(std::function<void(int)> cb)
{
std::cout << "SomeAPI about to do async work\n";
m_future = std::async(std::launch::async, [](auto cb)
{
std::cout << "Async thread sleeping 10 seconds (Doing work).\n";
std::this_thread::sleep_for(std::chrono::seconds{ 10 });
// Do a bunch of work and set a status indicating success or failure.
// Assume 0 is success.
int status = 0;
std::cout << "Executing callback.\n";
cb(status);
std::cout << "Callback Executed.\n";
}, cb);
};
std::future<void> m_future;
};
class SomeOtherClass
{
public:
void SetSuccess(int success) { m_success = success; }
private:
bool m_success = false;
};
class SomeClass : public std::enable_shared_from_this<SomeClass>
{
public:
SomeClass(SomeAPI* api)
: m_api(api)
{
}
void DoWorkUnsafe()
{
std::cout << "DoWorkUnsafe about to pass callback to async executer.\n";
// Call DoWork on the API.
// DoWork takes some time.
// When DoWork is finished, it calls the callback that we sent in.
m_api->DoWork([this](int status)
{
// Undefined behavior
m_value = 17;
// Crash
m_data->SetSuccess(true);
ReportSuccess();
});
}
void DoWorkSafe()
{
// Create a weak point from a shared pointer to this.
std::weak_ptr<SomeClass> this_ = shared_from_this();
std::cout << "DoWorkSafe about to pass callback to async executer.\n";
// Capture the weak pointer.
m_api->DoWork([this_](int status)
{
// Test the weak pointer.
if (auto sp = this_.lock())
{
std::cout << "Async work finished.\n";
// If its good, then we are still alive and safe to execute on this.
sp->m_value = 17;
sp->m_data->SetSuccess(true);
sp->ReportSuccess();
}
});
}
private:
void ReportSuccess()
{
// Tell everyone who cares that a thing has succeeded.
};
SomeAPI* m_api;
std::shared_ptr<SomeOtherClass> m_data = std::shared_ptr<SomeOtherClass>();
int m_value;
};
int main()
{
std::shared_ptr<SomeAPI> api = std::make_shared<SomeAPI>();
std::shared_ptr<SomeClass> someClass = std::make_shared<SomeClass>(api.get());
someClass->DoWorkSafe();
// Comment out the above line and uncomment the below line
// to see the unsafe behavior.
//someClass->DoWorkUnsafe();
std::cout << "Deleting someClass\n";
someClass.reset();
std::cout << "Main thread sleeping for 20 seconds.\n";
std::this_thread::sleep_for(std::chrono::seconds{ 20 });
return 0;
}
FWIW, I have used debugging checks for (this != NULL) in assertions before which have helped catch defective code. Not that the code would have necessarily gotten too far with out a crash, but on small embedded systems that don't have memory protection, the assertions actually helped.
On systems with memory protection, the OS will generally hit an access violation if called with a NULL this pointer, so there's less value in asserting this != NULL. However, see Pavel's comment for why it's not necessarily worthless on even protected systems.
Your method will most likely (may vary between compilers) be able to run and also be able to return a value. As long as it does not access any instance variables. If it tries this it will crash.
As others pointed out you can not use this test to see if an object has been deleted. Even if you could, it would not work, because the object may be deleted by another thread just after the test but before you execute the next line after the test. Use Thread synchronization instead.
If this is null there is a bug in your program, most likely in the design of your program.
I'd also add that it's usually better to avoid null or NULL. I think the standard is changing yet again here but for now 0 is really what you want to check for to be absolutely sure you're getting what you want.
This is just a pointer passed as the first argument to a function (which is exactly what makes it a method). So long as you're not talking about virtual methods and/or virtual inheritance, then yes, you can find yourself executing an instance method, with a null instance. As others said, you almost certainly won't get very far with that execution before problems arise, but robust coding should probably check for that situation, with an assert. At least, it makes sense when you suspect it could be occuring for some reason, but need to track down exactly which class / call stack it's occurring in.
I know this is a old question, however I thought I will share my experience with use of Lambda capture
#include <iostream>
#include <memory>
using std::unique_ptr;
using std::make_unique;
using std::cout;
using std::endl;
class foo {
public:
foo(int no) : no_(no) {
}
template <typename Lambda>
void lambda_func(Lambda&& l) {
cout << "No is " << no_ << endl;
l();
}
private:
int no_;
};
int main() {
auto f = std::make_unique<foo>(10);
f->lambda_func([f = std::move(f)] () mutable {
cout << "lambda ==> " << endl;
cout << "lambda <== " << endl;
});
return 0;
}
This code segment faults
$ g++ -std=c++14 uniqueptr.cpp
$ ./a.out
Segmentation fault (core dumped)
If I remove the std::cout statement from lambda_func The code runs to completion.
It seems like, this statement f->lambda_func([f = std::move(f)] () mutable { processes lambda captures before member function is invoked.

std::future still valid after calling get() (which throws an exception)

According to cppreference, after calling std::future::get:
valid() is false after a call to this method.
Additionally, from cplusplus.com:
Once the shared state is ready, the function unblocks and returns (or throws) releasing its shared state. This makes the future object no longer valid: this member function shall be called once at most for every future shared state.
And under Exception safety:
The function throws the exception stored in the shared state when the provider makes it ready by setting it to an exception. Note that in this case a basic guarantee is offered, with the future object being modified to no longer be a valid future (which is itself a valid state for object of this type, despite its name).
Neither description makes a distinction between a call to get which returns a value versus one that throws an exception regarding the invalidation of the future object.
However, the described behavior is not what I'm seeing with this example code:
#include <chrono>
#include <future>
#include <iostream>
#include <stdexcept>
int foo()
{
throw std::runtime_error("foo exception");
}
int main()
{
std::future<int> futInt;
futInt = std::async(std::launch::async, []() { return foo(); });
while( !(futInt.valid() && futInt.wait_for(std::chrono::milliseconds(0)) == std::future_status::ready) )
;
if( futInt.valid() )
{
int val;
try
{
val = futInt.get();
}
catch( const std::exception& e )
{
std::cout << e.what() << std::endl;
}
}
if( futInt.valid() )
{
std::cout << "This is TOTALLY UNEXPECTED!!!" << std::endl;
}
else
{
std::cout << "This is expected." << std::endl;
}
return 0;
}
The output I see is:
foo exception
This is TOTALLY UNEXPECTED!!!
I'm using Visual Studio Premium 2013, Version 12.0.30501.00 Update 2. Is this a bug with the compiler or, in fact, correct behavior in the case of an exception? I've been unable to find any bug reports concerning this, so wasn't sure if it was expected behavior.
Edit - <future> implementation investigation
Digging into the std::future implementation a bit, the _Associated_state object is marked _Retrieved = true; AFTER checking and throwing the associated exception (if any):
virtual _Ty& _Get_value(bool _Get_only_once)
{ // return the stored result or throw stored exception
unique_lock<mutex> _Lock(_Mtx);
if (_Get_only_once && _Retrieved)
_Throw_future_error(
make_error_code(future_errc::future_already_retrieved));
if (_Exception)
_Rethrow_future_exception(_Exception);
_Retrieved = true;
_Maybe_run_deferred_function(_Lock);
while (!_Ready)
_Cond.wait(_Lock);
if (_Exception)
_Rethrow_future_exception(_Exception);
return (_Result);
}
My guess is that the exception check and _Retrieved = true; should be swapped - the object should immediately be set as retrieved (after the _Get_only_once check) and then all other logic should follow. Ergo, compiler bug.
Edit - workaround
I think the following should suffice in lieu of directly calling get until a fix is implemented:
template<typename T>
T getFromFuture(std::future<T>& fut)
{
try
{
return fut.get();
}
catch( ... )
{
fut = {};
throw;
}
}
I compiled on Linux with gcc 5.2.0 and clang 3.7.0 -- both times with 64 Bit.
Running the program always results in
foo exception
This is expected.
It looks to me like Visual 2013 handles this incorrectly.
See also:
C++ ยง30.6.6/16-17
Throws: the stored exception, if an exception was stored in the shared state.
Postcondition: valid() == false.
The postcondition is mentioned after the throws and thus has to always hold, even if an exception is thrown. At least that is my interpretation, though I do not speak standardese.
I guess you should probably try also with Visual Studio 2015 and report a bug if that shows the same handling.

Can segmentation fault be caused by exhaustion of memory ?

I am solving a problem on codechef.
I have coded the algorithm of the problem and it runs fine on the test cases. Although, when I run it on codechef(online), it throws segmentation fault.
I have double checked that, I am not accessing any inaccessible memory locations, although I suspect that my program could have taken up huge amount of memory.
So, my question is that Can segmentation fault be thrown, when there is no more memory available for the program to execute. Something like OutOfMemoryException in C#
This depends on the way you allocate memory and whether you check for errors when doing so. E.g. malloc would return NULL on an out-of-memory condition. A failure to check that may lead to dereferencing NULL which would result in a segmentation fault. If you use new of C++, it would throw an exception instead.
In reality though when a program does excessive memory allocations it usually gets the system RAM overcommitted and its process is killed by an OOM killer before its malloc would start returning NULLs - unless most of the allocated memory is actually unused.
As Kerrek mentioned in the comments an excessive usage of automatic storage or a call stack which is too deep can cause a SEG-fault e.g (on coliru):
void foo(){ foo(); }
int main() {
foo();
return 0;
}
or (on coliru):
#include <iostream>
int main()
{
int a[50000000];
std::cout << a[500];
}
So to sum it up you have to be aware of your systems limitations, for example some recursive brute force solutions are sometimes theoretically OK and should work but are rather impractical (yes, this is a vague example but the OP did not mention what problem is being solved nor how so I wanted to give the above at least some context...).
There are actually two situations
1. You try to allocate too much from the call stack, then you'll receive a signal. An exception can't be caught
int main() {
try {
std::array<int,10000000> arr;
cout << arr[40] << endl;
}
catch(const std::exception& e) {
cout << e.what() << endl;
}
return 0;
}
2. You try to allocate too much dynamic memory, then you'll receive an exception
int main() {
try {
std::vector<int> arr;
arr.resize(1000000000);
cout << arr[40] << endl;
}
catch(const std::exception& e) {
cout << e.what() << endl;
}
return 0;
}
You can try it live on ideone.

What could be overriding the return code from main()?

I have a rather odd occurrence happening that I haven't been able to nut out yet.
I have test case that is supposed to catch errors and return the appropriate error code from main, but /sometimes/ on test runs the program returns 0 even when the error code is non zero.
The exception class thrown is:
class exit_request {
public:
explicit exit_request(int code = 0) : m_code(code) {}
int code() const { return m_code; }
private:
int m_code;
};
The test case code is:
int main(int argc, char* argv[])
{
try {
// Do some test case stuff
// Eventually, due to the supplied command line arguments,
// we expect an exit_request() to be thrown from within
// library code.
}
catch (exit_request& exp) {
std::cout << "Exit Request:" << exp.code() << std::endl;
return exp.code();
}
catch (std::exception& err) {
std::cout << "Error: " << err.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
In many runs of this test case, everything works as expected: The exit_request() exception is thrown, caught, exp.code() is printed (its value is 2), and the return code from the process is 2.
However, very occasionally, the return code from the process is 0 (i.e. no failure), even though exp.code() is printed as 2.
Can anyone help explain a situation in which this can occur? i.e. the return value from main is changed from non-zero to zero before the process exits?
This is occurring on Windows 7 (x64), with MSVC++ 2010 Express, building a x86 (32-bit) application. I have not seen this odd failure on any of our other Windows or Linux platforms, or compilers, but that doesn't necessarily mean it couldn't happen in those environments.
If you have any atexit handlers that call exit(0), or any static-storage-duration objects whose destructors do that, it might explain what you're seeing. They get executed after your return statement. It's undefined behavior, which could explain why you only see it happen sometimes.
Maybe you are not throwing the exception correctly...
I mean that from the function called or processing done in try block, you are throwing exception of some other type.
Try to write a default catch block for that.

Checking if this is null

Does it ever make sense to check if this is null?
Say I have a class with a method; inside that method, I check this == NULL, and if it is, return an error code.
If this is null, then that means the object is deleted. Is the method even able to return anything?
Update: I forgot to mention that the method can be called from multiple threads and it may cause the object to be deleted while another thread is inside the method.
Does it ever make sense to check for this==null? I found this while doing a code review.
In standard C++, it does not, because any call on a null pointer is already undefined behavior, so any code relying on such checks is non-standard (there's no guarantee that the check will even be executed).
Note that this holds true for non-virtual functions as well.
Some implementations permit this==0, however, and consequently libraries written specifically for those implementations will sometimes use it as a hack. A good example of such a pair is VC++ and MFC - I don't recall the exact code, but I distinctly remember seeing if (this == NULL) checks in MFC source code somewhere.
It may also be there as a debugging aid, because at some point in the past this code was hit with this==0 because of a mistake in the caller, so a check was inserted to catch future instances of that. An assert would make more sense for such things, though.
If this == null then that means the object is deleted.
No, it doesn't mean that. It means that a method was called on a null pointer, or on a reference obtained from a null pointer (though obtaining such a reference is already U.B.). This has nothing to do with delete, and does not require any objects of this type to have ever existed.
Your note about threads is worrisome. I'm pretty sure you have a race condition that can lead to a crash. If a thread deletes an object and zeros the pointer, another thread could make a call through that pointer between those two operations, leading to this being non-null and also not valid, resulting in a crash. Similarly, if a thread calls a method while another thread is in the middle of creating the object, you may also get a crash.
Short answer, you really need to use a mutex or something to synchonize access to this variable. You need to ensure that this is never null or you're going to have problems.
I know that this is old but I feel like now that we're dealing with C++11-17 somebody should mention lambdas. If you capture this into a lambda that is going to be called asynchronously at a later point in time, it is possible that your "this" object gets destroyed before that lambda is invoked.
i.e passing it as a callback to some time-expensive function that is run from a separate thread or just asynchronously in general
EDIT: Just to be clear, the question was "Does it ever make sense to check if this is null" I am merely offering a scenario where it does make sense that might become more prevalent with the wider use of modern C++.
Contrived example:
This code is completely runable. To see unsafe behavior just comment out the call to safe behavior and uncomment the unsafe behavior call.
#include <memory>
#include <functional>
#include <iostream>
#include <future>
class SomeAPI
{
public:
SomeAPI() = default;
void DoWork(std::function<void(int)> cb)
{
DoAsync(cb);
}
private:
void DoAsync(std::function<void(int)> cb)
{
std::cout << "SomeAPI about to do async work\n";
m_future = std::async(std::launch::async, [](auto cb)
{
std::cout << "Async thread sleeping 10 seconds (Doing work).\n";
std::this_thread::sleep_for(std::chrono::seconds{ 10 });
// Do a bunch of work and set a status indicating success or failure.
// Assume 0 is success.
int status = 0;
std::cout << "Executing callback.\n";
cb(status);
std::cout << "Callback Executed.\n";
}, cb);
};
std::future<void> m_future;
};
class SomeOtherClass
{
public:
void SetSuccess(int success) { m_success = success; }
private:
bool m_success = false;
};
class SomeClass : public std::enable_shared_from_this<SomeClass>
{
public:
SomeClass(SomeAPI* api)
: m_api(api)
{
}
void DoWorkUnsafe()
{
std::cout << "DoWorkUnsafe about to pass callback to async executer.\n";
// Call DoWork on the API.
// DoWork takes some time.
// When DoWork is finished, it calls the callback that we sent in.
m_api->DoWork([this](int status)
{
// Undefined behavior
m_value = 17;
// Crash
m_data->SetSuccess(true);
ReportSuccess();
});
}
void DoWorkSafe()
{
// Create a weak point from a shared pointer to this.
std::weak_ptr<SomeClass> this_ = shared_from_this();
std::cout << "DoWorkSafe about to pass callback to async executer.\n";
// Capture the weak pointer.
m_api->DoWork([this_](int status)
{
// Test the weak pointer.
if (auto sp = this_.lock())
{
std::cout << "Async work finished.\n";
// If its good, then we are still alive and safe to execute on this.
sp->m_value = 17;
sp->m_data->SetSuccess(true);
sp->ReportSuccess();
}
});
}
private:
void ReportSuccess()
{
// Tell everyone who cares that a thing has succeeded.
};
SomeAPI* m_api;
std::shared_ptr<SomeOtherClass> m_data = std::shared_ptr<SomeOtherClass>();
int m_value;
};
int main()
{
std::shared_ptr<SomeAPI> api = std::make_shared<SomeAPI>();
std::shared_ptr<SomeClass> someClass = std::make_shared<SomeClass>(api.get());
someClass->DoWorkSafe();
// Comment out the above line and uncomment the below line
// to see the unsafe behavior.
//someClass->DoWorkUnsafe();
std::cout << "Deleting someClass\n";
someClass.reset();
std::cout << "Main thread sleeping for 20 seconds.\n";
std::this_thread::sleep_for(std::chrono::seconds{ 20 });
return 0;
}
FWIW, I have used debugging checks for (this != NULL) in assertions before which have helped catch defective code. Not that the code would have necessarily gotten too far with out a crash, but on small embedded systems that don't have memory protection, the assertions actually helped.
On systems with memory protection, the OS will generally hit an access violation if called with a NULL this pointer, so there's less value in asserting this != NULL. However, see Pavel's comment for why it's not necessarily worthless on even protected systems.
Your method will most likely (may vary between compilers) be able to run and also be able to return a value. As long as it does not access any instance variables. If it tries this it will crash.
As others pointed out you can not use this test to see if an object has been deleted. Even if you could, it would not work, because the object may be deleted by another thread just after the test but before you execute the next line after the test. Use Thread synchronization instead.
If this is null there is a bug in your program, most likely in the design of your program.
I'd also add that it's usually better to avoid null or NULL. I think the standard is changing yet again here but for now 0 is really what you want to check for to be absolutely sure you're getting what you want.
This is just a pointer passed as the first argument to a function (which is exactly what makes it a method). So long as you're not talking about virtual methods and/or virtual inheritance, then yes, you can find yourself executing an instance method, with a null instance. As others said, you almost certainly won't get very far with that execution before problems arise, but robust coding should probably check for that situation, with an assert. At least, it makes sense when you suspect it could be occuring for some reason, but need to track down exactly which class / call stack it's occurring in.
I know this is a old question, however I thought I will share my experience with use of Lambda capture
#include <iostream>
#include <memory>
using std::unique_ptr;
using std::make_unique;
using std::cout;
using std::endl;
class foo {
public:
foo(int no) : no_(no) {
}
template <typename Lambda>
void lambda_func(Lambda&& l) {
cout << "No is " << no_ << endl;
l();
}
private:
int no_;
};
int main() {
auto f = std::make_unique<foo>(10);
f->lambda_func([f = std::move(f)] () mutable {
cout << "lambda ==> " << endl;
cout << "lambda <== " << endl;
});
return 0;
}
This code segment faults
$ g++ -std=c++14 uniqueptr.cpp
$ ./a.out
Segmentation fault (core dumped)
If I remove the std::cout statement from lambda_func The code runs to completion.
It seems like, this statement f->lambda_func([f = std::move(f)] () mutable { processes lambda captures before member function is invoked.