<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=us-ascii"><meta name=Generator content="Microsoft Word 15 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
font-size:12.0pt;
font-family:"Calibri",sans-serif;
mso-ligatures:standardcontextual;}
span.EmailStyle17
{mso-style-type:personal-compose;
font-family:"Calibri",sans-serif;
color:windowtext;}
.MsoChpDefault
{mso-style-type:export-only;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
{page:WordSection1;}
--></style></head><body lang=EN-US link="#0563C1" vlink="#954F72" style='word-wrap:break-word'><div class=WordSection1><p class=MsoNormal>Since this is my first attempt to submit code to the GNC project I thought I’d pass my approach through the established<o:p></o:p></p><p class=MsoNormal>developers first.<o:p></o:p></p><p class=MsoNormal>I am interested in converting GNC code from C to C++ which will occur over time so that the review quanta is not too overwhelming.<o:p></o:p></p><p class=MsoNormal>I plan to convert build targets to only use the C++ compiler over time.<o:p></o:p></p><p class=MsoNormal>Anything that is exposed with C linkage I plan to carry forward expecting at some point all the callers will be C++ as well and most if not all of the C-linkage requirements will go away.<o:p></o:p></p><p class=MsoNormal>Any C++ code that is called from C-code will need a mechanism to prevent C++ exceptions from bleeding back.<o:p></o:p></p><p class=MsoNormal>I’ve developed a header file except-fence.hpp that provides the required fencing.<o:p></o:p></p><p class=MsoNormal>My first patch will be just this header file and the associated test files, so no GNC code will be affected initially.<o:p></o:p></p><p class=MsoNormal>I wanted to make the footprint small since I expect the fences will eventually be removed.<o:p></o:p></p><p class=MsoNormal>My approach is to replace the definition if the C-API functions with a macro that defines a stub C-API (extern “C”)<o:p></o:p></p><p class=MsoNormal>Which instantiates an ExceptFence object and uses the “forward_to” method call a local static function with the original body.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>For Example:<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>const char *<o:p></o:p></p><p class=MsoNormal>func1(int a, gpointer b) // defined as extern “C” in header file<o:p></o:p></p><p class=MsoNormal>{<o:p></o:p></p><p class=MsoNormal>…<o:p></o:p></p><p class=MsoNormal>}<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Becomes:<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>SAFE_C_API_ARGS(const char *, func1, (int a, gpointer b), (a, b))<o:p></o:p></p><p class=MsoNormal>{<o:p></o:p></p><p class=MsoNormal>…<o:p></o:p></p><p class=MsoNormal>}<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Which (essentially) expands to:<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>static const char *loc_func1(int a, gpointer b);<o:p></o:p></p><p class=MsoNormal>extern “C” const char *func1(int a, gpointer b)<o:p></o:p></p><p class=MsoNormal>{<o:p></o:p></p><p class=MsoNormal> ExceptFence exf;<o:p></o:p></p><p class=MsoNormal> return exf.forward_to(loc_func1, a, b);<o:p></o:p></p><p class=MsoNormal>}<o:p></o:p></p><p class=MsoNormal>static const char *loc_func1 (int a, gpointer b)<o:p></o:p></p><p class=MsoNormal>{<o:p></o:p></p><p class=MsoNormal>…<o:p></o:p></p><p class=MsoNormal>}<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>The essence of forward_to is the following:<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal> template<typename Func, typename... Args><o:p></o:p></p><p class=MsoNormal> auto forward_to(Func&& func, Args&&... args)<o:p></o:p></p><p class=MsoNormal> {<o:p></o:p></p><p class=MsoNormal> try {<o:p></o:p></p><p class=MsoNormal> m_except_data.exception_hit = true;<o:p></o:p></p><p class=MsoNormal> auto result = func(std::forward<Args>(args)...);<o:p></o:p></p><p class=MsoNormal> m_except_data.exception_hit = false;<o:p></o:p></p><p class=MsoNormal> return result;<o:p></o:p></p><p class=MsoNormal> }<o:p></o:p></p><p class=MsoNormal> catch (const std::exception& ex) {<o:p></o:p></p><p class=MsoNormal> m_except_data.exception_type = &typeid(ex);<o:p></o:p></p><p class=MsoNormal> m_except_data.exception_message = ex.what();<o:p></o:p></p><p class=MsoNormal> }<o:p></o:p></p><p class=MsoNormal> using ReturnType = std::invoke_result_t<Func, Args...>;<o:p></o:p></p><p class=MsoNormal> if constexpr (std::is_integral_v<ReturnType>) {<o:p></o:p></p><p class=MsoNormal> return static_cast<ReturnType>(m_exception_error_integer);<o:p></o:p></p><p class=MsoNormal> } else if constexpr (std::is_pointer_v<ReturnType>) {<o:p></o:p></p><p class=MsoNormal> return static_cast<ReturnType>(nullptr);<o:p></o:p></p><p class=MsoNormal> } else {<o:p></o:p></p><p class=MsoNormal> return ReturnType{};<o:p></o:p></p><p class=MsoNormal> }<o:p></o:p></p><p class=MsoNormal> }<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>This definition of forward_to() supports functions that return integer types, pointer types, and structure types.<o:p></o:p></p><p class=MsoNormal>That appears to support most of what we need that I’ve seen.<o:p></o:p></p><p class=MsoNormal>There are 4 different SAFE_C_API macros to support all the combinations of void args and void return types.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Anyway, if there are concerns about this approach, or request for more details please let me know.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Thanks for your attention and support.<o:p></o:p></p><p class=MsoNormal>-russ<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal><o:p> </o:p></p></div></body></html>