Skip to content

Instantly share code, notes, and snippets.

@FatihBAKIR
Last active April 19, 2017 23:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FatihBAKIR/dd125cf4f06cbf13bb4434f79e7f1d43 to your computer and use it in GitHub Desktop.
Save FatihBAKIR/dd125cf4f06cbf13bb4434f79e7f1d43 to your computer and use it in GitHub Desktop.
only_on_stack type
#include <iostream>
#include <stdexcept>
#if _MSC_VER
#define NO_INLINE __declspec(noinline)
#else
#define NO_INLINE __attribute__ ((noinline))
#endif
struct stack_marker
{
thread_local static uint8_t* marker;
uint8_t stk;
stack_marker()
{
if (marker != nullptr)
{
throw std::runtime_error("second twice marker! don't do it");
}
marker = &stk;
}
};
thread_local uint8_t* stack_marker::marker = nullptr;
void sort3(uint8_t* (&a)[3])
{
if (a[0] > a[1])
std::swap(a[0], a[1]);
if (a[0] > a[2])
std::swap(a[0], a[2]);
if (a[1] > a[2])
std::swap(a[1], a[2]);
}
class only_on_stack
{
uint8_t place;
public:
NO_INLINE only_on_stack(int x)
{
uint8_t a;
if (!stack_marker::marker)
{
// not initialized yet, either forgot to put stack_marker in main
// or we are running before main, which is static storage
//throw std::runtime_error("only on stack object created in non-stack");
std::cout << x << ": I'm NOT on stack\n";
return;
}
uint8_t* ptrs[] = {
stack_marker::marker,
&place,
&a
};
sort3(ptrs);
if (ptrs[1] == &place) // place must be in the middle
{
std::cout << x << ": I'm on stack\n";
}
else
{
//throw std::runtime_error("only_on_stack object created in non-stack");
std::cout << x << ": I'm NOT on stack\n";
}
}
};
only_on_stack static_storage(1);
thread_local only_on_stack tl_storage(4);
int NO_INLINE stuff()
{
only_on_stack oos(2);
only_on_stack test(5);
}
int main()
{
stack_marker mrk;
stuff();
auto test = new only_on_stack(3);
tl_storage; // access thread local to construct
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment