Gnucash c++

John Ralls jralls at ceridwen.us
Tue Aug 12 11:50:54 EDT 2014


On Aug 12, 2014, at 7:22 AM, Aaron Laws <dartme18 at gmail.com> wrote:

> On Mon, Aug 11, 2014 at 4:52 PM, Christian Stimming <christian at cstimming.de>
> wrote:
> 
>> Hi Aaron,
>> 
>> thanks for investing time in Gnucash and also in its development towards
>> more
>> future-proof programming technologies.
> 
> 
> The pleasure is mine.
> 
> 
>> I was a bit puzzled about the benefit
>> of switching the "normal compiling" from C to C++, just by itself. IMHO,
>> there
>> is of course an immediate benefit if the data structures move from plain C
>> structs to C++ classes, with constructor/destructor and such. If you plan
>> to
>> do such a transition with any of gnucash's data structures, of course every
>> code using those will have to be C++. However, just changing this into C++
>> doesn't also solve the problem here: The usage of the C structs in the
>> code is
>> just that: C structs, with foo_new() and foo_delete() functions and maybe
>> even
>> glib's reference counting. To really use C++ classes instead, every single
>> usage of those old C idioms will have to be replaced by proper C++
>> constructs.
>> IMHO, "just" switching the C compiling to C++ doesn't quite bring you much
>> gain here. Do you think it helps you much?
> 
> 
> Thanks for asking! You're right, changing the compiler from gcc to g++ does
> nothing to directly improve maintainability or performance of the code in
> question. As I see it, the gains come after that painful process. I'll go
> ahead and repeat the strategy I'm investigating for reference:
> 
> 1) Make all code compile as c++ code
> 2) Add poison to make it idiomatic c++ code
> 3) Make higher level changes
> 
> Part of the strategy includes this plan being followed rather strictly.
> Using this plan, step 3 brings with it the possibility of converting
> interfaces to c++ (giving classes constructors and destructors, making
> templated algorithms, etc.). Currently, for instance, the guid object is
> not usable as proper c++ code even if there were a client code file that
> could take advantage of it, because there is no c++ interface in the header
> file; if there were, all the C code would barf at compile-time.
> 
> 
>> [...snip...] I see some more
>> benefit when changing individual data structures to C++, then switching the
>> old C functions into wrappers that make the new C++ behaviour available to
>> the
>> C side.
> 
> 
> In a way, that's just what I'm going for. The only way to make typedef
> struct _gncGuid {...} GncGUID; into class GncGUID; is to make sure that
> every compilation unit (which uses GUID) knows what "class GncGUID;" means!
> At that point, it would be no problem to make GncGUID a class (or a typedef
> for a boost class), and even manage it with smart pointers or whatever.
> This can be done right alongside (for example) the existing glib date
> interface. With this kind of change, we're freed from the requirement that
> each code file communicates with the other code files "in C". We are now
> free to speak a different language as we desire, as we are able, and,
> importantly, at our liesure.
> 
> 
>> This means the existing C code can continue to compile in C, and the
>> next steps would rather be to open the possibility for new C++ code such as
>> unittests and maybe new GUI code in C++ (or python or something similar).
> 
> 
> So it sounds like you're talking about introducing new c++ code that uses
> the existing C interfaces, which I think is an obvious win. The next win
> that I'm striving to see is the existing C code start to use C++ idioms,
> data structures, etc.
> 
> It would be nice if all that makes sense, but I know better than to even
> hope for that :-).  Thanks again for asking, and please help me clarify by
> asking more questions!

When you compile a struct in C++, it gets a set of constructors and a destructor regardless of whether you write them or not.

The GUI API that we're currently using is in C, as are all of the container classes (GList mostly) and the GValue data-passing mechanism that's for the moment central to KVP and the SQL backend. Quite a lot of those APIs work with callbacks that must be in C linkage, and those callbacks are typically static functions. Few of them are pre-declared, so it will be a tedious job to find each one and create an extern "C" declaration for it. In the container case it's wasted work: It gets thrown away when the using class is rewritten in C++ with std containers. 

Take a look at the way I've wrapped GncNumeric with gnc_numeric in https://github.com/jralls/gnucash/blob/libmpdecimal/src/libqof/qof/gnc-numeric.h
C++ code can use class GncNumeric directly (once the operator overloads are added) while C code continues to use the gnc_numeric API.

I'm in favor of cleaning out the C++ reserved words (looks like namespace and class are the primary offenders; the Gnome rubric is to use klass, so let's do that instead of clas). Doing so will speed up the file-by-file conversion when the time comes. I don't think that trying to make everything C++ linkage is a good use of time because most of the work will be thrown away. I'd much rather you continue to do C++ conversions in QOF rather than pursuing this shotgun effort.

Regards,
John Ralls





More information about the gnucash-devel mailing list