On May 5, 2014, at 5:33 PM, Colin Law <[email protected]> wrote:

> On 5 May 2014 21:45, John Ralls <[email protected]> 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


_______________________________________________
gnucash-devel mailing list
[email protected]
https://lists.gnucash.org/mailman/listinfo/gnucash-devel

Reply via email to