> On Feb 5, 2026, at 3:03 PM, <[email protected]> <[email protected]> > wrote: > > Since this is my first attempt to submit code to the GNC project I thought > I’d pass my approach through the established > developers first. > 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. > I plan to convert build targets to only use the C++ compiler over time. > 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. > Any C++ code that is called from C-code will need a mechanism to prevent C++ > exceptions from bleeding back. > I’ve developed a header file except-fence.hpp that provides the required > fencing. > My first patch will be just this header file and the associated test files, > so no GNC code will be affected initially. > I wanted to make the footprint small since I expect the fences will > eventually be removed. > My approach is to replace the definition if the C-API functions with a macro > that defines a stub C-API (extern “C”) > Which instantiates an ExceptFence object and uses the “forward_to” method > call a local static function with the original body. > For Example: > const char * > func1(int a, gpointer b) // defined as extern “C” in header file > { > … > } > Becomes: > SAFE_C_API_ARGS(const char *, func1, (int a, gpointer b), (a, b)) > { > … > } > Which (essentially) expands to: > static const char *loc_func1(int a, gpointer b); > extern “C” const char *func1(int a, gpointer b) > { > ExceptFence exf; > return exf.forward_to(loc_func1, a, b); > } > static const char *loc_func1 (int a, gpointer b) > { > … > } > The essence of forward_to is the following: > template<typename Func, typename... Args> > auto forward_to(Func&& func, Args&&... args) > { > try { > m_except_data.exception_hit = true; > auto result = func(std::forward<Args>(args)...); > m_except_data.exception_hit = false; > return result; > } > catch (const std::exception& ex) { > m_except_data.exception_type = &typeid(ex); > m_except_data.exception_message = ex.what(); > } > using ReturnType = std::invoke_result_t<Func, Args...>; > if constexpr (std::is_integral_v<ReturnType>) { > return static_cast<ReturnType>(m_exception_error_integer); > } else if constexpr (std::is_pointer_v<ReturnType>) { > return static_cast<ReturnType>(nullptr); > } else { > return ReturnType{}; > } > } > This definition of forward_to() supports functions that return integer > types, pointer types, and structure types. > That appears to support most of what we need that I’ve seen. > There are 4 different SAFE_C_API macros to support all the combinations of > void args and void return types. > Anyway, if there are concerns about this approach, or request for more > details please let me know. > Thanks for your attention and support.
Getting rid of C entirely requires changing the GUI framework; the minimum effort would be gtkmm but even that will be a lot of work. It isn’t going to happen any time soon. Also to consider is that exceptions either can’t be allowed to leak through the Python and Scheme bindings or those bindings need to acquire exception converters. Just switching to compiling C code with a C++ compiler doesn’t introduce exceptions so the need to wrap calls in try/catch is limited to cases when the function is reimplemented to use some C++ thing that throws. Note that loc_func1 still has to check ext.m_except_data.exception_hit and if it’s true do something with the rest. I suspect that that something will turn out to be sufficiently not generic that having the template won’t really save much over just catching the exception in the implementation function or writing a C wrapper that handles exceptions in a way that’s appropriate for the execution context at hand. BTW, “m_exception_error_integer” is a problem because it implies that that’s a single value used for all cases and it’s not hard at all to think of cases where different values would be needed for signaling an error. Regards, John Ralls _______________________________________________ gnucash-devel mailing list [email protected] https://lists.gnucash.org/mailman/listinfo/gnucash-devel
