Spinlock code using atomic_flag in C++ is not compiling in Mac - c++11

I tried to write a simple Spinlock code in C++ but the code is not getting compiled in the Mac but is compiling on other gcc compilers.
#include<iostream>
#include<thread>
#include<atomic>
using namespace std;
class SpinLock
{
public:
atomic_flag flag;
SpinLock() : flag(ATOMIC_FLAG_INIT) {}
void lock()
{
while(flag.test_and_set());
}
void unlock()
{
flag.clear();
}
};
SpinLock spin;
void critical_section()
{
spin.lock();
for(int i = 0 ; i < 10 ; i++)
{
cout << i << " ";
}
cout << endl;
spin.unlock();
}
int main()
{
thread t1(critical_section);
thread t2(critical_section);
t1.join();
t2.join();
}
I tried checking version of clang installed in my machine at the version is:
Apple clang version 13.1.6 (clang-1316.0.21.2)
Target: arm64-apple-darwin21.4.0
Thread model: posix
Can any one help me in the fact that why code is not getting compiled?

atomic_flag (const atomic_flag&T) is a deleted constructor, and STL defines only two constructors for the atomic_flag (another one is default).
ATOMIC_FLAG_INIT usually doesn't even refer to a value to feed the constructor with, it's just a macro to call some kind of default initialization (for MSVC it's defined as curly brackets {}). You may want to initialize your flag like this:
class SpinLock
{
public:
atomic_flag flag = ATOMIC_FLAG_INIT;
SpinLock() {}
...

Related

C++ macOS clang 12 x86 base exception not caught in library when compiling host app with -fno-rtti

Problem - shared library catching base exceptions not working when host app compiled without RTTI on macOS using clang 12 on x86 platform (works with arm).
Shared library code
#include <iostream>
void test_exception_handling()
{
try
{
throw std::out_of_range("out_of_range");
}
catch (const std::exception& exc)
{
std::cout << "ALL GOOD: caught std::exception" << std::endl;
}
catch (...)
{
std::cout << "FAIL: caught ..." << std::endl;
}
}
host app code (compiled with -fno-rtti)
#include <iostream>
#define EXPORT __attribute__ ((visibility("default")))
void EXPORT test_exception_handling();
int main()
{
test_exception_handling();
try {
//} catch (const std::out_of_range&) {
} catch (const std::exception&) {
}
return 0;
}
When uncommenting
} catch (const std::out_of_range&)
library code no longer enters catch(const std::exception&) block.
Question - why is this happening? Does it mean that it is not supported to mix rtti and non-rtti code?
Thank you.

C++ 11 passing shared_pointer like with std::any

at the moment I'm facing following problem. I need a member function in a derived class that can handle different shared_ptr types and do custom stuff with it. The base class should make sure that such a member function is implemented but the specific shared_ptr types are only known when a other developer create a new derived class. Therefore, templates are not a solution due to the fact that c++ not support virtual template functions.
The shared_ptrs hold protobuf message specific publisher or subscriber. Here a snipped of code:
std::shared_ptr<Publisher<ProtobufMessageType1>> type1 = std::make_shared<ProtobufMessageType1>();
std::shared_ptr<Publisher<ProtobufMessageType2>> type2 = std::make_shared<ProtobufMessageType2>();
class derived : base
{
void takeThePointerAndDoSpecificStuff( std::shared_ptr<PubOrSub<SpecificProtobufMessage>>) override
{
// check type and bind specific callback
}
}
One solution could be casting shared_ptr to base class but it is not possible because the protobuf message base class is pure virtual. Another solution is to cast the raw pointer and only transfer this one but I need the share_ptr reference count also in the method ( due to binding).
So I look further for a solution and std::any could be one but the problem here is that c++11 not have a std::any (sure could use boost but I try to avoid that).
So now I'm out of ideas how to solve the problem but perhaps you have one and can help me.
Thank you for any answer in advance.
One solution could be casting shared_ptr to base class but it is not possible because the protobuf message base class is pure virtual
That's simply not true. You can have shared pointers to abstract bases just fine:
Live On Coliru
#include <memory>
#include <iostream>
struct Base {
virtual ~Base() = default;
virtual void foo() const = 0;
};
struct D1 : Base { virtual void foo() const override { std::cout << __PRETTY_FUNCTION__ << "\n"; } };
struct D2 : Base { virtual void foo() const override { std::cout << __PRETTY_FUNCTION__ << "\n"; } };
int main() {
std::shared_ptr<Base> b = std::make_shared<D1>();
std::shared_ptr<Base> c = std::make_shared<D2>();
b->foo();
c->foo();
}
Prints
virtual void D1::foo() const
virtual void D2::foo() const
More Ideas
Even in case you do not have a common base (or a base at all) you can still use shared_pointer. One particularly powerful idiom is to use shared_pointer<void>:
Live On Coliru
#include <memory>
#include <iostream>
struct D1 {
void foo() const { std::cout << __PRETTY_FUNCTION__ << "\n"; }
~D1() { std::cout << __PRETTY_FUNCTION__ << "\n"; }
};
struct D2 {
void bar() const { std::cout << __PRETTY_FUNCTION__ << "\n"; }
~D2() { std::cout << __PRETTY_FUNCTION__ << "\n"; }
};
int main() {
std::shared_ptr<void> b = std::make_shared<D1>();
std::shared_ptr<void> c = std::make_shared<D2>();
std::static_pointer_cast<D1>(b)->foo();
std::static_pointer_cast<D2>(c)->bar();
}
Prints
void D1::foo() const
void D2::bar() const
D2::~D2()
D1::~D1()
See: http://www.boost.org/doc/libs/1_66_0/libs/smart_ptr/doc/html/smart_ptr.html#techniques_using_shared_ptr_void_to_hold_an_arbitrary_object

What changes between C++98 and C++11 show difference in behavior?

I was reading the following post:
What changes introduced in C++14 can potentially break a program written in C++11?
and also the isocpp page:
https://isocpp.org/files/papers/p0636r0.html
So I became curious, according to the Standard: What changes introduced in C++11 can potentially break a program written in C++98?
Big one that stands out -- throwing exceptions from destructors.
In C++98 you can have programs that do this and work fine if you are careful.
In C++11 you will often have to explicitly declare the dtor noexcept(false).
Nice blog post here, on Andrzej's C++ blog.
In short, the following program used to run successfully in C++03 (under some definition of “success”):
struct S
{
~S() { throw runtime_error(""); } // bad, but acceptable
};
int main()
{
try { S s; }
catch (...) {
cerr << "exception occurred";
}
cout << "success";
}
In C++11, the same program will trigger the call to std::terminate.
Here is another case related to destructors are noexcept(true) in C++11:
// A simple program that demonstrates how C++11 and pthread_cancel don't play
// nicely together.
//
// If you build without C++11 support (g++ threadkill.cpp -lpthread), the
// application will work as expected. After 5 seconds, main() will cancel the
// thread it created and the program will successfully exit.
//
// If you build with C++11 support(g++ -std=c++11 threadkill.cpp -lpthread),
// the program will crash because the abi::__forced_unwind exception will
// escape the destructor, which is implicitly marked as noexcept(true) in
// C++11. If you mark the destructor as noexcept(false), the program does
// not crash.
#include <iostream>
#include <unistd.h>
#include <string.h>
class sleepyDestructorObject
{
public:
~sleepyDestructorObject() //noexcept(false)
{
std::cout << "sleepy destructor invoked" << std::endl;
while(true)
{
std::cout << "." << std::flush;
sleep(1);
}
}
};
void* threadFunc( void* lpParam )
{
sleepyDestructorObject sleepy;
return NULL;
}
int main(int argc, char** argv)
{
pthread_t tThreadID;
pthread_create(&tThreadID, NULL, threadFunc, NULL);
sleep(5);
pthread_cancel(tThreadID);
pthread_join(tThreadID, NULL);
return 0;
}
Original reference:
https://gcc.gnu.org/ml/gcc-help/2015-08/msg00036.html

compiler order with gcc 4.8.5

My gcc version is 4.8.5
posix gcc version 4.8.5 20150623 (Red Hat 4.8.5-4) (GCC)
I have two cpp files:
1.cpp and 2.cpp
while there is a static function in 1.cpp called by 2.cpp。
In most machine,we should like this:
g++ 2.cpp 1.cpp
or it will cause compile error or runtime error。
However,in my machine with gcc 4.8.5,I must compile using “g++ 1.cpp 2.cpp” to make it run successful。
Is this the property of gcc4.8.5? or there is something wrong on my soft,or I used it wrong?
==============================================================
My machine is centos7 installed on virtulbox of mac. Here is my code:
1.h
#include <map>
using namespace std;
class A {
private:
A();
static A _instance;
map<int, int> test_map;
public:
static A& get_instance();
static void fun();
};
1.cpp
#include <iostream>
#include "1.h"
using namespace std;
A A::_instance;
A::A() {
cout << "A::A()\n";
}
A& A::get_instance() {
cout << "A::get_instance()\n";
return A::_instance;
// static A instance;
// return instance;
}
void A::fun() {
cout << "A::fun()\n";
get_instance().test_map[1];
}
main.cpp
#include <iostream>
#include "1.h"
using namespace std;
int test() {
cout << "test()\n";
A::fun();
return 0;
}
int y = test();
int main() {
cout << "main()\n";
A::fun();
}
In most machine and in what I see in the web, we should compile like this:
g++ main.cpp 1.cpp
But in my machine, I must compile like this:
g++ 1.cpp main.cpp
what's wrong with my machine or my gcc?
I think you are facing the static initialization order fiasco which is a classical C++ bug. If initialization function test() in main.cpp is called before constructor for A::_instance has been called, your code will access uninitialized A::_instance::test_map field which is likely to cause segmentation fault. I suggest you rewrite getInstance to create instance when needed:
A *A::_instance;
A& A::get_instance() {
cout << "A::get_instance()\n";
if(!_instance)
_instance = new A;
return *A::_instance;
}
As a side note, I suggest you to use AddressSanitizer to autodetect this and similar types of errors.

Visual Studio: Vector of Unique Pointers of Subclasses Crashes

In Visual Studio 2015, the code shown below crashes at the exit of foo(), with this error message: HEAP[NameOfExecutable.exe]: Invalid address specified to RtlValidateHeap( 00520000, 005332D4 )
Notes:
When I remove the "virtual" keyword from B::bob(), the program works perfectly fine.
The program runs correctly from a command-line (outside of Visual Studio), when compiled with "g++ -std=c++11".
Using std::move() within push_back() didn't change the output.
#include <vector>
#include <memory>
#include <iostream>
class A
{
int a;
};
class B : public A
{
int b;
virtual void bob() { };
};
void foo()
{
std::vector<std::unique_ptr<A>> test;
test.push_back(std::unique_ptr<B>(new B));
}
int main()
{
foo();
std::cout << "Reached the end\n";
std::cin.get();
}
What am I doing wrong? Thanks for any help!
If you debug the code, you'll notice that the exception arises at the exit point of foo() - when the destructor for test is called.
Both std::vector and std::unique_ptr manage their memory of course, so somewhere at this point B object that you just allocated will be destroyed.
The problem here is that you store it by an A pointer, so the A class destructor will be called.
To fix that, just introduce public virtual destructor to 'A':
class A
{
int a;
public:
virtual ~A() {}
};

Resources