QDBM and transactions

Stefan Bellon sbellon at sbellon.de
Mon Nov 1 09:40:12 CET 2004


Stefan Bellon wrote:
> Matthias Andree wrote:

> > 1. the cmpkey function has seen an incompatible change to align QDBM
> >    and DB dump order - only affects people who have used the new
> >    Villa API version. dump/load should fix this.

> I don't completely understand. What are your changes? Could you post
> your cmpkey?

Ok, I have seen your cmpkey in 0.92.100.cvs now. You assign values
between incompatible types:

int cmpkey(const char *aptrin, int asiz, const char *bptrin, int bsiz)
{
    int aiter, biter;
    const unsigned char *aptr = aptrin;
    const unsigned char *bptr = bptrin;

This does work with GCC but not with compilers really strict adhering
to the C standard (Norcroft C on RISC OS e.g.).

I asked this question once to one of the Norcroft C maintainers and got
this answer back (with permission to quote it):

-----BEGIN QUOTE-----
Okay. "6.5.16.1 Simple Assignment" in C99 gives the list of
possibilities for types in a simple assignment. This assignment can
only possibly fall into the case:

   "both operands are pointers to qualified or unqualified versions of
    compatible types, and the type pointed to by the left has all the
    qualifiers of the type pointed to be the right."

(qualifiers being const, volatile, restrict).

So the question is whether "char" and "unsigned char" are compatible
types. The standard doesn't appear to state this directly in the
normative sections, but by chasing down all the references to what ARE
compatible types, you can conclude that they are not. And more
directly, the informative footnote 35 in section "6.2.5 Types" says:
   
   Irrespective of the choice made [whether char is signed or unsigned],
   char is a separate type from the other two and is not compatible with
   either.

Some compilers only issue a warning for such assignments, or may
incorrectly silently allow it. The C standard does require a diagnostic
to be issued, as the assignments violate a specific constraint. And in
Norcroft C, all required diagnostics are errors (or serious errors).
-----END QUOTE-----

So, if you want aptr and bptr to be of type (unsigned char *) and
aptrin and bptrin are of type (char *), then you _have_ to cast them:

    const unsigned char *aptr = (unsigned char *) aptrin;
    const unsigned char *bptr = (unsigned char *) bptrin;

-- 
Stefan Bellon



More information about the bogofilter-dev mailing list