Fix for dbi_initialize crash if libdbi >= 0.9.0 (notably on Ubuntu 14.04)

John Ralls jralls at ceridwen.us
Mon May 5 18:18:31 EDT 2014


On May 5, 2014, at 5:33 PM, Colin Law <clanlaw at gmail.com> wrote:

> On 5 May 2014 21:45, John Ralls <jralls at ceridwen.us> wrote:
>> ...
>> It's because dbi_initialize_r() is the only function that needs to write to the dbi_instance; everything else just reads it. That makes managing the memory the application's job and allows other approaches than allocating it on the heap, including the static allocation that Moritz chose to use in his implementation. The "_r" suffix to the function name is analogous to gmtime_r, localtime_r, etc. which take a struct tm* from the caller instead of using a static in the library code. Making the rest of the functions use pass-by-copy saves a multi-threaded program from having to synchronize their calls, though using const dbi_inst* instead would have allowed for cleaner semantics when they choose to put it on the heap.
> 
> That makes sense, though the fact that two users separately got the
> interface wrong does make one wonder whether it is ideal.  It also
> does not help that it is actually defined as void* or something
> similar so the compiler was not able to identify that the original
> call to initialize was wrong (I think, I have not looked at it in
> detail).

Of course it's not ideal, but it's the best one can do without proper constructors that are part of the language. In C++ one can simply have 

  static DbiInstance dbi_inst = DbiInstance();

The compiler does more or less the same thing that dbi_initialize_r() does, but hides the gory details so that the programmer has to go out of his way to screw it up. As a consequence the compiler can be very strict about void*: The programmer has to explicitly declare or cast a parameter to void* in the function call or get a warning.

Regards,
John Ralls




More information about the gnucash-devel mailing list