Difference between revisions of "C++"

From GnuCash
Jump to: navigation, search
(Initial Version)
 
(some comments from cstim)
Line 9: Line 9:
 
* The conversion will take a long time, so interoperability with the existing C code is essential. Only C++ and Objective C can be interspersed with C one line at a time, but Objective-C is not available on Microsoft platforms using native tools.
 
* The conversion will take a long time, so interoperability with the existing C code is essential. Only C++ and Objective C can be interspersed with C one line at a time, but Objective-C is not available on Microsoft platforms using native tools.
 
* There are two widely-used C++-based cross-platform GUI libraries, [http://www.wxwidgets.org wxWidgets] and [http://qt-project.org/ Qt]. Both support all three major desktop platforms and iOS.
 
* There are two widely-used C++-based cross-platform GUI libraries, [http://www.wxwidgets.org wxWidgets] and [http://qt-project.org/ Qt]. Both support all three major desktop platforms and iOS.
 +
 +
:cstim's comment: In addition to this reasoning, everyone is invited to have a look at some already existing C++ wrapper objects in src/optional/gtkmm/gncmm, which make use of the glibmm/gtkmm C++ wrapper library around glib/gtk to present classes that "look like" real C++ classes. Using this sort of wrappers would even make it possible to do a step-by-step onversion to C++ - as long as we accept the dependency on glibmm/glib in the core objects for some time being. See [[Cutecash]] on how to compile this part of the code with [[CMake]].
  
 
== Developer Preparation ==
 
== Developer Preparation ==
Line 31: Line 33:
 
== C++11/14 ==
 
== C++11/14 ==
 
A greatly improved language was released in 2011. The standards committee expects to release some tweaks and fixes in 2014. Fortunately most of those fixes are already implemented in already-available compilers. Unfortunately, we have to support older systems and older compilers. No worries: [http://www.boost.org Boost] is the proving-ground for many of those features and Boost libraries are available to implement those features with older compilers.
 
A greatly improved language was released in 2011. The standards committee expects to release some tweaks and fixes in 2014. Fortunately most of those fixes are already implemented in already-available compilers. Unfortunately, we have to support older systems and older compilers. No worries: [http://www.boost.org Boost] is the proving-ground for many of those features and Boost libraries are available to implement those features with older compilers.
 +
 +
:cstim adds: On the other hand, given the time frame you're talking about here, you can very well set C++11 as a prerequisite for a C++ gnucash.
  
 
== Dependencies ==
 
== Dependencies ==
GLib provides a ton of useful cross-platform support functions, macros, and classes. Almost all of them are replaceable with algorithms and containers from the Standard Library. BTW, std::vector<> is vastly more efficient than GList. The rest of what GLib and GObject provide, along with a couple of things that we did ourselves (GUID, gnc-date, gnc-numeric, and QofSignal) are provided by the [http://www.boost.org Boost] libraries. The goal is to have no dependencies other than the Standard Library and Boost except in the GUI, import-export, and backends.
+
GLib provides a ton of useful cross-platform support functions, macros, and classes. Almost all of them are replaceable with algorithms and containers from the Standard Library. BTW, std::vector<> is vastly more efficient than GList (cstim: but std::vector isn't the correct analogy to GList; instead std::list is). The rest of what GLib and GObject provide, along with a couple of things that we did ourselves (GUID, gnc-date, gnc-numeric, and QofSignal) are provided by the [http://www.boost.org Boost] libraries. The goal is to have no dependencies other than the Standard Library and Boost except in the GUI, import-export, and backends.

Revision as of 08:01, 18 November 2013

Converting Gnucash to C++ from sort-of GObject

The underlying rationale to this page is a long thread on the gnucash-devel list titled Beyond 2.6. It's worth frequent review, as there are a lot of good ideas as well as valid concerns expressed there.

To summarize, Gnucash has grown over 10 years without a lot of thought on continuing design. The old design documents are still in the tree, and though they might get deleted soon will always be in git history. They haven't been updated in more than 10 years. The reimplementation in GObject was done with a poor understanding of how GObject's emulation of object orientation works. That's not surprising; it was done in the early days of GObject, and GObject itself is complicated and generally lacking in the "syntactic sugar' which makes real object oriented languages usable.

There are lots of object oriented languages, though, so why C++?

  • C++ compilers are available on all major platforms except Android, and there's a shim library available there which may work to wrap a C++ library in a Java GUI. While Java is available on all the desktop platforms, it isn't available on iOS.
  • The conversion will take a long time, so interoperability with the existing C code is essential. Only C++ and Objective C can be interspersed with C one line at a time, but Objective-C is not available on Microsoft platforms using native tools.
  • There are two widely-used C++-based cross-platform GUI libraries, wxWidgets and Qt. Both support all three major desktop platforms and iOS.
cstim's comment: In addition to this reasoning, everyone is invited to have a look at some already existing C++ wrapper objects in src/optional/gtkmm/gncmm, which make use of the glibmm/gtkmm C++ wrapper library around glib/gtk to present classes that "look like" real C++ classes. Using this sort of wrappers would even make it possible to do a step-by-step onversion to C++ - as long as we accept the dependency on glibmm/glib in the core objects for some time being. See Cutecash on how to compile this part of the code with CMake.

Developer Preparation

C++ is easier to learn and to write than is GObject. Low bar. GObject is a bitch to write, and takes a lot of work to understand. C++ is easy to write, but it still takes some work to understand. Some very strongly recommended (I'd say required, but I don't want to be too scary) reading:

  • Bjarne Stroustroup, The C++ Programming Language, Fourth Edition, Addison-Wesley, 2013.
  • Nicolai Josuttis, The C++ Standard Library, A Tutorial and Reference, Second Edition, Addison-Wesley, 2012
  • Scott Meyers, Effective C++, More Effective C++, Effective STL, Addison-Wesley, 2005, 1996, and 2001 respectively. Meyers has promised a new Effective C++ updated for C++11/14 for Spring 2014.
  • Herb Sutter, Exceptional C++, Addison-Wesley, 1999

If you buy all of them new, it will run well over $200 in the US and probably more in Europe. Meyers's and Sutter's books are widely available used at a fraction of the cost, and understanding them will make you a much better C++ programmer. There's a fair amount of overlap between Stroustroup and Josuttis. Of the two, Josuttis is much more approachable for the working developer; Stroustroup is a bit academic. OTOH, Josuttis's coverage is a bit narrow, being mostly focused on the Standard Library. Earlier and therefore cheaper, especially used, versions of either are fine, except that they won't cover the recent developments in the language.

Study in particular templates and generic programming. I found it easier to grasp than rewiring my brain from structured to object oriented design, but that was a long and painful process. The seminal work about that was

  • James Coplien, Advanced C++ Programming Styles and Idioms, Addison-Wesley, 1991

which I found utterly impenetrable, but I haven't tried to read it in a long time. The book that really made it popular is

  • Andrei Alexandrescu, Modern C++ Design, Addison-Wesley, 2001

Stroustroup added a large section in the fourth edition of The C++ Programming Language; earlier editions have a chapter which discusses the feature but doesn't go into much detail about what to do with it. The important thing about Templates is that they allow one to push off some of the work and overhead consumed by pure OO onto the compiler, making the compiled result faster and smaller. Templates are also very helpful in reducing dependencies between classes, a major problem with Gnucash's current code. Moreover, most of the Standard Library and Boost are written using templates and using those 'libraries' effectively depends on a good understanding of templates.

One other note about templates: They're much better than preprocessor macros. While macros work in C++ just like they do in C, they're very clumsy compared to templates. Whenever possible replace macros with const variables, constfuncs, and templates. Remember that the compiler can't really understand macros, but it does understand templates.

Also familiarize yourself with the Standard Library Algorithms. These are highly optimized implementations of common things you need to do. You're not likely to have time to write better code, so use the algorithms every chance you get.

C++11/14

A greatly improved language was released in 2011. The standards committee expects to release some tweaks and fixes in 2014. Fortunately most of those fixes are already implemented in already-available compilers. Unfortunately, we have to support older systems and older compilers. No worries: Boost is the proving-ground for many of those features and Boost libraries are available to implement those features with older compilers.

cstim adds: On the other hand, given the time frame you're talking about here, you can very well set C++11 as a prerequisite for a C++ gnucash.

Dependencies

GLib provides a ton of useful cross-platform support functions, macros, and classes. Almost all of them are replaceable with algorithms and containers from the Standard Library. BTW, std::vector<> is vastly more efficient than GList (cstim: but std::vector isn't the correct analogy to GList; instead std::list is). The rest of what GLib and GObject provide, along with a couple of things that we did ourselves (GUID, gnc-date, gnc-numeric, and QofSignal) are provided by the Boost libraries. The goal is to have no dependencies other than the Standard Library and Boost except in the GUI, import-export, and backends.