Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>There is no such thing as an anonymous function in C (C++ is irrelevant here, as the function must abide by the C calling convention).</p> <p>The only thing you can do is <em>shiver</em> access globals from the handler, probably global <em>variables</em> (and not constants which would be fine).</p> <p>I advise making those globals <em>thread local</em> to avoid multithreading issues, but it is still <em>bad</em> in the sense that global variables make for more brittle applications.</p> <hr> <p><strong>How to ?</strong></p> <p><em>Note: as Luc Danton patiently explained to me, a signal may interrupt any non-atomic activity, and thus reading from a global is safe only if it is a lock-free atomic (or a few other things). <strong>Unfortunately <code>std::function</code> may not be so, depending on your implementation</strong>, I will still leave this code to explain how it could be done <strong>providing that <code>std::function</code> accesses are atomic</strong>.</em></p> <p>It is possible to create a trampoline that will call stateful stuff, isolating thread and allowing re-entrant calls.</p> <pre><code>typedef std::function&lt;void(int)&gt; SignalHandlerType; extern thread_local ignalHandlerType SignalHandler; </code></pre> <p>And we create the following accessor (passed to signal):</p> <pre><code>void handle_signal(int const i) { if (SignalHandler) { SignalHandler(i); } } </code></pre> <p>as well as the following RAII setter:</p> <pre><code>class SignalSetter: boost::noncopyable { public: SignalSetter(int signal, SignalHandlerType&amp;&amp; sh): signal(signal), chandler(0), handler(sh) { chandler = std::signal(signal, &amp;handle_signal&lt;T&gt;); swap(SignalHandler, handler); } ~SignalSetter() { std::signal(signal, chandler); swap(SignalHandler, handler); } private: typedef void(*CHandlerType)(int); int signal; CHandlerType chandler; SignalHandlerType handler; }; </code></pre> <p><em>Note: both the global variable and the <code>handle_signal</code> could be <code>private</code> to the <code>SignalSetter</code> class... but since <code>std::signal</code> is not...</em></p> <p>Expected usage:</p> <pre><code>int main(int argc, char* argv[]) { SignalSetter setter(SIGFPE, [argc, argv]() { std::cout &lt;&lt; argc &lt;&lt; ": " &lt;&lt; argc &lt;&lt; std::endl; }); // do what you want. } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload