Why in hash function use 5381?

Discussion in 'C Programming' started by anguo, Jan 3, 2004.

  1. anguo

    anguo Guest

    i find in many hash function use 5381,for exampla:
    static constmap_hash hash(char *pchData, int iLen)
    {
    unsigned char cBuf;
    constmap_hash ulHashId;
    ulHashId = 5381;
    while (iLen > 0)
    {
    cBuf = *pchData++ - 'A';
    if (cBuf <= 'Z' - 'A')
    {
    cBuf += 'a' - 'A';
    }
    ulHashId = ((ulHashId << 5) + ulHashId) ^ cBuf;
    --iLen;
    }
    return ulHashId;
    }
    Can anyone tell me why use 5381 ?
    thanks!!
    anguo, Jan 3, 2004
    #1
    1. Advertising

  2. anguo

    Ben Pfaff Guest

    (anguo) writes:

    > i find in many hash function use 5381,for exampla:


    [...]

    > Can anyone tell me why use 5381 ?


    This webpage implies that it is a random number selected by Dan
    Bernstein: <http://www.cs.yorku.ca/~oz/hash.html>. Presumably
    everyone else just used the same number.
    --
    int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.\
    \n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
    );while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p\
    );}return 0;}
    Ben Pfaff, Jan 3, 2004
    #2
    1. Advertising

  3. Ben Pfaff wrote:
    > (anguo) writes:
    >>i find in many hash function use 5381,for exampla:

    > [...]
    >>Can anyone tell me why use 5381 ?


    > This webpage implies that it is a random number selected by Dan
    > Bernstein: <http://www.cs.yorku.ca/~oz/hash.html>. Presumably
    > everyone else just used the same number.


    Except that it is not so very random looking: 5381 = 012405. This looks
    like something deeper is involved. The 001/010/100/000/101 raises the
    question about the choice of the last octal digit, though.


    --
    Martin Ambuhl
    Martin Ambuhl, Jan 3, 2004
    #3
  4. Ben Pfaff wrote:

    >
    > --
    > int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.\
    > \n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
    > );while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p\
    > );}return 0;}


    huh "Just another C hacker" :)

    Ben.c: (in function main)
    Ben.c:9:18: Variable i initialized to type arbitrary unsigned integral type,
    expects int: sizeof(p) / 2

    Ben.c:10:9: Function strchr shadows outer declaration
    An outer declaration is shadowed by the local declaration.

    Specification of strchr:
    [function (char *, int) returns char *]

    Ben.c:11:7: Function putchar shadows outer declaration
    Specification of putchar:
    [function (int) returns int]

    Ben.c:12:10: Test expression for while not boolean, type char: *q
    Test expression type is not boolean.

    Ben.c:14:12: Variable strchr used before definition
    An rvalue is used that may not be initialized to a value on some execution
    path.
    Ben.c:17:7: Variable putchar used before definition

    Ben.c:17:7: Return value (type int) ignored: putchar(p)
    Result returned by function call is not used.


    Cheers :)
    Jean-Michel Collard, Jan 3, 2004
    #4
  5. anguo

    Ben Pfaff Guest

    Jean-Michel Collard <> writes:

    > Ben Pfaff wrote:
    >
    > > --
    > > int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.\
    > > \n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
    > > );while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p\
    > > );}return 0;}

    >
    > huh "Just another C hacker" :)
    >
    > [...many warnings snipped...]


    It's perfectly well-defined, if obfuscated, C. It's not meant to
    be lint-clean. Based on what I've seen from some versions of
    lint, a lot of lint warnings are simply nonsensical, so that's
    not even a good goal for real-world code.
    Ben Pfaff, Jan 3, 2004
    #5
  6. anguo

    Richard Bos Guest

    Jean-Michel Collard <> wrote:

    > Ben Pfaff wrote:
    >
    > > int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.\
    > > \n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
    > > );while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p\
    > > );}return 0;}

    >
    > huh "Just another C hacker" :)
    >
    > Ben.c: (in function main)
    > Ben.c:9:18: Variable i initialized to type arbitrary unsigned integral type,
    > expects int: sizeof(p) / 2


    Correct for this constant value, though.

    > Ben.c:10:9: Function strchr shadows outer declaration
    > An outer declaration is shadowed by the local declaration.


    Where, pray, is this "outer declaration" to be found?

    > Ben.c:11:7: Function putchar shadows outer declaration


    And ditto?

    > Ben.c:12:10: Test expression for while not boolean, type char: *q
    > Test expression type is not boolean.


    Yer_what_?

    > Ben.c:14:12: Variable strchr used before definition
    > An rvalue is used that may not be initialized to a value on some execution
    > path.
    > Ben.c:17:7: Variable putchar used before definition


    Erm... boggle.

    > Ben.c:17:7: Return value (type int) ignored: putchar(p)
    > Result returned by function call is not used.


    Gosh. Lint really _is_ prehistoric, isn't it?

    Richard
    Richard Bos, Jan 5, 2004
    #6
  7. Richard Bos wrote:
    > Jean-Michel Collard <> wrote:
    >
    >
    >>Ben Pfaff wrote:
    >>
    >>
    >>>int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.\
    >>> \n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
    >>>);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p\
    >>>);}return 0;}

    >>
    >>huh "Just another C hacker" :)
    >>
    >>Ben.c: (in function main)
    >>Ben.c:9:18: Variable i initialized to type arbitrary unsigned integral type,
    >> expects int: sizeof(p) / 2

    >
    >
    > Correct for this constant value, though.


    Eh, lint can't tell that.

    >
    >
    >>Ben.c:10:9: Function strchr shadows outer declaration
    >> An outer declaration is shadowed by the local declaration.

    >
    >
    > Where, pray, is this "outer declaration" to be found?


    The '#include'd header file?

    The old-style implicit declaration of everything returning an int?


    >>Ben.c:12:10: Test expression for while not boolean, type char: *q
    >> Test expression type is not boolean.

    >
    >
    > Yer_what_?


    Here's where lint is a bit too pedantic (well, here's a single instance
    out of possibly thousands ;)): C acts like it has a boolean type
    sometimes, and it certainly has a boolean context. lint doesn't know,
    and can't be made to know, that things other than boolean-returning
    relational expressions (such as (a > 5) or (f <= 12)) can meaningfully
    be used in a boolean context.

    IMNSHO, lint here goes from pedantic to incorrect. Even the earliest
    versions of C would gleefully, and conformantly, accept things that
    aren't strictly booleans where it imposes a boolean context. For lint to
    complain about such things has never been helpful.

    >
    >
    >>Ben.c:14:12: Variable strchr used before definition
    >> An rvalue is used that may not be initialized to a value on some execution
    >> path.
    >>Ben.c:17:7: Variable putchar used before definition

    >
    >
    > Erm... boggle.


    lint's stupid sometimes.

    >
    >
    >>Ben.c:17:7: Return value (type int) ignored: putchar(p)
    >> Result returned by function call is not used.

    >
    >
    > Gosh. Lint really _is_ prehistoric, isn't it?


    According to K&R2, putchar() does indeed return an int. I suspect a cast
    to void would silence lint, but it's hardly worth it, is it?

    [OT]
    I use splint, a lint-a-like, myself, and splint gives you the warning,
    the explanation, and the argument you can pass to splint to make it shut
    up about the damned warning. I usually invoke splint with no flags once,
    then with a few to weed out the more egregiously inane whinings.
    [/OT]
    August Derleth, Jan 5, 2004
    #7
  8. anguo

    Ben Pfaff Guest

    August Derleth <> writes:

    > lint's stupid sometimes.


    lint is stupid to the point of uselessness. As just one example,
    at least one variety of lint emits a warning for the following:
    long x = 0;
    saying that the initializer is not of the proper type.
    --
    "I'm not here to convince idiots not to be stupid.
    They won't listen anyway."
    --Dann Corbit
    Ben Pfaff, Jan 5, 2004
    #8
  9. On Mon, 5 Jan 2004, August Derleth wrote:
    >
    > Richard Bos wrote:
    > > Jean-Michel Collard <> wrote:
    > >>Ben Pfaff wrote:
    > >>
    > >>>int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.\
    > >>> \n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
    > >>>);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p\
    > >>>);}return 0;}
    > >>
    > >>huh "Just another C hacker" :)
    > >>
    > >>Ben.c: (in function main)
    > >>Ben.c:9:18: Variable i initialized to type arbitrary unsigned integral type,
    > >> expects int: sizeof(p) / 2

    > >
    > >
    > > Correct for this constant value, though.

    >
    > Eh, lint can't tell that.


    It could if it tried hard enough. ;-)


    > >>Ben.c:10:9: Function strchr shadows outer declaration
    > >> An outer declaration is shadowed by the local declaration.

    > >
    > > Where, pray, is this "outer declaration" to be found?

    >
    > The '#include'd header file?
    >
    > The old-style implicit declaration of everything returning an int?


    Ben's .sig #includes no headers, and "implicit declarations" are
    implicit for a reason. They're superseded by "real" declarations.
    K&R1 even does this in several places, IIRC. So the bottom line is,
    this warning is completely bogus. But my guess is that the guy who
    ran lint on the .sig did wrongly #include <string.h> -- how else
    would lint be down to line 10 in the source already?


    > >>Ben.c:12:10: Test expression for while not boolean, type char: *q
    > >> Test expression type is not boolean.

    > >
    > > Yer_what_?

    >
    > Here's where lint is a bit too pedantic (well, here's a single instance
    > out of possibly thousands ;)): C acts like it has a boolean type
    > sometimes, and it certainly has a boolean context. lint doesn't know,
    > and can't be made to know, that things other than boolean-returning
    > relational expressions (such as (a > 5) or (f <= 12)) can meaningfully
    > be used in a boolean context.
    >
    > IMNSHO, lint here goes from pedantic to incorrect. Even the earliest
    > versions of C would gleefully, and conformantly, accept things that
    > aren't strictly booleans where it imposes a boolean context. For lint to
    > complain about such things has never been helpful.


    It might be helpful in cases like

    if (a=b)

    The problems are (1) lint uses the word "boolean" like the programmer
    is supposed to know what it means, and which "types" are "boolean"
    enough for lint -- but C90 doesn't have boolean types -- and (2) lint
    should really know about common idioms like 'if (*q)'. It makes a
    large bit of sense to warn about 'if (a+b)' or the like, for the sake
    of lint-ness, but lint should know better than to complain in this
    case.


    > >>Ben.c:17:7: Return value (type int) ignored: putchar(p)
    > >> Result returned by function call is not used.

    > >
    > > Gosh. Lint really _is_ prehistoric, isn't it?

    >
    > According to K&R2, putchar() does indeed return an int. I suspect a cast
    > to void would silence lint, but it's hardly worth it, is it?


    Some old code, and some overly-portable code, does use casts to
    void. We even get questions about (void)printf here occasionally.
    I can only assume there's some way to switch off this warning in
    modern lints; it would get really obnoxious if you tried to lint a
    big source file.

    > [OT]
    > I use splint, a lint-a-like, myself, and splint gives you the warning,
    > the explanation, and the argument you can pass to splint to make it shut
    > up about the damned warning. I usually invoke splint with no flags once,
    > then with a few to weed out the more egregiously inane whinings.


    Excellent. I wish gcc would do this too, for its warnings. It
    seems like a very nice feature.

    > [/OT]


    -Arthur
    Arthur J. O'Dwyer, Jan 5, 2004
    #9
  10. anguo

    Eric Sosman Guest

    Ben Pfaff wrote:
    >
    > August Derleth <> writes:
    >
    > > lint's stupid sometimes.

    >
    > lint is stupid to the point of uselessness. As just one example,
    > at least one variety of lint emits a warning for the following:
    > long x = 0;
    > saying that the initializer is not of the proper type.


    I once encountered a *compiler* that complained about

    float f = 0.0;

    .... because of the potential loss of precision in the
    conversion of `double' to `float'. Perhaps the goal of
    the compiler vendor was "Get Nothing Right!"

    --
    Eric Sosman, Jan 5, 2004
    #10
  11. anguo

    Sidney Cadot Guest

    Eric Sosman wrote:

    > I once encountered a *compiler* that complained about
    >
    > float f = 0.0;
    >
    > ... because of the potential loss of precision in the
    > conversion of `double' to `float'. Perhaps the goal of
    > the compiler vendor was "Get Nothing Right!"


    I'm not sure I wholly disagree with the compiler in this case.

    Could you explain why you think a warning is so over-the-top here?

    Best regards,

    Sidney
    Sidney Cadot, Jan 6, 2004
    #11
  12. In article <btd0ng$rf6$>,
    Sidney Cadot <> wrote:

    > Eric Sosman wrote:
    >
    > > I once encountered a *compiler* that complained about
    > >
    > > float f = 0.0;
    > >
    > > ... because of the potential loss of precision in the
    > > conversion of `double' to `float'. Perhaps the goal of
    > > the compiler vendor was "Get Nothing Right!"

    >
    > I'm not sure I wholly disagree with the compiler in this case.
    >
    > Could you explain why you think a warning is so over-the-top here?


    It would be a strange implementation where an assignment of the double
    precision number 0.0 to a variable of type float would produce a loss of
    precision. Same for 1.0 or 0.5 .

    If you have an assignment

    float f = <double precision constant>;

    then it would be trivial for the compiler to check whether or not
    (float)constant == (double)constant or not. Then the compiler can either
    give a warning: "Warning: Loss of precision" or be quiet if there is no
    loss of precision.
    Christian Bau, Jan 6, 2004
    #12
  13. anguo

    pete Guest

    Christian Bau wrote:
    >
    > In article <btd0ng$rf6$>,
    > Sidney Cadot <> wrote:
    >
    > > Eric Sosman wrote:
    > >
    > > > I once encountered a *compiler* that complained about
    > > >
    > > > float f = 0.0;
    > > >
    > > > ... because of the potential loss of precision in the
    > > > conversion of `double' to `float'. Perhaps the goal of
    > > > the compiler vendor was "Get Nothing Right!"

    > >
    > > I'm not sure I wholly disagree with the compiler in this case.
    > >
    > > Could you explain why you think a warning is so over-the-top here?

    >
    > It would be a strange implementation where an assignment of the double
    > precision number 0.0 to a variable of type float would produce a loss of
    > precision. Same for 1.0 or 0.5 .
    >
    > If you have an assignment
    >
    > float f = <double precision constant>;
    >
    > then it would be trivial for the compiler to check whether or not
    > (float)constant == (double)constant or not.
    > Then the compiler can either give a warning:
    > "Warning: Loss of precision" or be quiet if there is no
    > loss of precision.


    If the implementation gives warnings based solely on the code,
    without regard for implementation defined behavior,
    then you'll have less new warnings when you port the code,
    assuming that you paid proper heed to the warnings.

    --
    pete
    pete, Jan 6, 2004
    #13
  14. anguo

    Sidney Cadot Guest

    Christian Bau wrote:

    > In article <btd0ng$rf6$>,
    > Sidney Cadot <> wrote:
    >
    >>Eric Sosman wrote:
    >>
    >>
    >>> I once encountered a *compiler* that complained about
    >>>
    >>> float f = 0.0;
    >>>
    >>>... because of the potential loss of precision in the
    >>>conversion of `double' to `float'. Perhaps the goal of
    >>>the compiler vendor was "Get Nothing Right!"

    >>
    >>I'm not sure I wholly disagree with the compiler in this case.
    >>
    >>Could you explain why you think a warning is so over-the-top here?

    >
    >
    > It would be a strange implementation where an assignment of the double
    > precision number 0.0 to a variable of type float would produce a loss of
    > precision. Same for 1.0 or 0.5 .


    Strange yes, but not impossible, as far as I can tell from the standard.
    I don't think there's a requirement that zero be exactly representable
    for floats/doubles. Of course, I wholly agree that an FP implementation
    would be seriously broken if it couldn't do this.

    > If you have an assignment
    >
    > float f = <double precision constant>;
    >
    > then it would be trivial for the compiler to check whether or not
    > (float)constant == (double)constant or not. Then the compiler can either
    > give a warning: "Warning: Loss of precision" or be quiet if there is no
    > loss of precision.


    Probably the compiler already said "*possible* loss of precision".

    Having warnings depend on implementation-defined things is perhaps not a
    good idea. To have a rather more interesting example:

    float x = 0.1;

    We would both, I think, consider the warning to be a good idea at least
    on radix-2 FP machines; however, I think it is also not unreasonable to
    get a warning on a radix-10 machine (will make porting efforts ever so
    much easier).

    Best regards, Sidney
    Sidney Cadot, Jan 6, 2004
    #14
  15. anguo

    Richard Bos Guest

    August Derleth <> wrote:

    > Richard Bos wrote:
    > > Jean-Michel Collard <> wrote:
    > >
    > >>Ben Pfaff wrote:
    > >>
    > >>>int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.\
    > >>> \n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
    > >>>);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p\
    > >>>);}return 0;}
    > >>
    > >>huh "Just another C hacker" :)
    > >>
    > >>Ben.c: (in function main)
    > >>Ben.c:9:18: Variable i initialized to type arbitrary unsigned integral type,
    > >> expects int: sizeof(p) / 2

    > >
    > > Correct for this constant value, though.

    >
    > Eh, lint can't tell that.


    Of course it can, for exactly the same reason that I can: in that
    context, p is a non-variable-sized array, which has constant size - 56,
    to be precise. sizeof p is therefore 56, and sizeof p/2 is 28, and 28
    _must_ convert correctly to int.


    > >>Ben.c:10:9: Function strchr shadows outer declaration
    > >> An outer declaration is shadowed by the local declaration.

    > >
    > > Where, pray, is this "outer declaration" to be found?

    >
    > The '#include'd header file?


    There _is_ no header file in that code.

    > The old-style implicit declaration of everything returning an int?


    That doesn't exist unless the function is called without an explicit
    declaration. Which it isn't.

    > >>Ben.c:12:10: Test expression for while not boolean, type char: *q
    > >> Test expression type is not boolean.

    > >
    > > Yer_what_?

    >
    > Here's where lint is a bit too pedantic


    No, it's talking out of its hat. The control expression of a while loop
    need not be "boolean" at all, whatever lint, in its poor addled
    imagination, thinks a "boolean" type is in pre-99 C.

    > C acts like it has a boolean type sometimes,


    Not unless you're using C99.

    > and it certainly has a boolean context.


    Yes. And in those contexts, _any_ scalar will suffice - all that is
    needed is that it can be tested for being-zero-or-not.

    > lint doesn't know, and can't be made to know, that things other than
    > boolean-returning relational expressions (such as (a > 5) or (f <= 12))
    > can meaningfully be used in a boolean context.


    In other words, lint is incorrigibly broken. Such uses are perfectly
    correct in C, and flagging them as wrong is simply not correct.

    > >>Ben.c:14:12: Variable strchr used before definition
    > >> An rvalue is used that may not be initialized to a value on some execution
    > >> path.
    > >>Ben.c:17:7: Variable putchar used before definition

    > >
    > > Erm... boggle.

    >
    > lint's stupid sometimes.


    Understatement of the year award granted on January 2nd already.

    > >>Ben.c:17:7: Return value (type int) ignored: putchar(p)
    > >> Result returned by function call is not used.

    > >
    > > Gosh. Lint really _is_ prehistoric, isn't it?

    >
    > According to K&R2, putchar() does indeed return an int.


    Yes. And according to the same K&R, there is no need to use the return
    value of every single expression. I note, for example, that lint does
    not complain about the various assignment statements, whose results are
    ignored as well.

    > I suspect a cast
    > to void would silence lint, but it's hardly worth it, is it?


    My point exactly. I haven't seen lint-shutting-up casts for ages, and it
    is indeed hardly worth the trouble to deface your code so badly if you
    can, with much less effort, throw the bloody dinosaur out the window and
    use a proper error-checking compiler.

    Richard
    Richard Bos, Jan 6, 2004
    #15
  16. anguo

    CBFalconer Guest

    Sidney Cadot wrote:
    > Eric Sosman wrote:
    >
    > > I once encountered a *compiler* that complained about
    > >
    > > float f = 0.0;
    > >
    > > ... because of the potential loss of precision in the
    > > conversion of `double' to `float'. Perhaps the goal of
    > > the compiler vendor was "Get Nothing Right!"

    >
    > I'm not sure I wholly disagree with the compiler in this case.
    >
    > Could you explain why you think a warning is so over-the-top here?


    I think the warning should be emitted. Consider:

    #define SOMEVALUE (0)

    #define BASEVAL ((SOMEVALUE) / 3.0)

    ..... globs of code ....

    float f, g;

    ..... further globs ....

    f = BASEVAL; /* WARNING TIME */
    g = 3 * BASEVAL; /* WARNING TIME */

    otherwise the apparently innocent future change of SOMEVALUE may
    trigger many confusing warnings.

    --
    Chuck F () ()
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net> USE worldnet address!
    CBFalconer, Jan 6, 2004
    #16
  17. anguo

    Joe Wright Guest

    Christian Bau wrote:
    >
    > In article <btd0ng$rf6$>,
    > Sidney Cadot <> wrote:
    >
    > > Eric Sosman wrote:
    > >
    > > > I once encountered a *compiler* that complained about
    > > >
    > > > float f = 0.0;
    > > >
    > > > ... because of the potential loss of precision in the
    > > > conversion of `double' to `float'. Perhaps the goal of
    > > > the compiler vendor was "Get Nothing Right!"

    > >
    > > I'm not sure I wholly disagree with the compiler in this case.
    > >
    > > Could you explain why you think a warning is so over-the-top here?

    >
    > It would be a strange implementation where an assignment of the double
    > precision number 0.0 to a variable of type float would produce a loss of
    > precision. Same for 1.0 or 0.5 .
    >
    > If you have an assignment
    >
    > float f = <double precision constant>;
    >
    > then it would be trivial for the compiler to check whether or not
    > (float)constant == (double)constant or not. Then the compiler can either
    > give a warning: "Warning: Loss of precision" or be quiet if there is no
    > loss of precision.


    I would doubt very much that the compiler checks that the double value
    can be assigned to float without loss of precision. Simply that
    assigning double to float might cause it.
    --
    Joe Wright http://www.jw-wright.com
    "Everything should be made as simple as possible, but not simpler."
    --- Albert Einstein ---
    Joe Wright, Jan 6, 2004
    #17
  18. Richard Bos wrote:

    > August Derleth <> wrote:
    >
    >
    >>Richard Bos wrote:
    >>
    >>>Jean-Michel Collard <> wrote:
    >>>
    >>>
    >>>>Ben Pfaff wrote:
    >>>>
    >>>>
    >>>>>int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.\
    >>>>>\n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
    >>>>>);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p\
    >>>>>);}return 0;}
    >>>>
    >>>>huh "Just another C hacker" :)
    >>>>
    >>>>Ben.c: (in function main)
    >>>>Ben.c:9:18: Variable i initialized to type arbitrary unsigned integral type,
    >>>> expects int: sizeof(p) / 2
    >>>
    >>>Correct for this constant value, though.

    >>
    >>Eh, lint can't tell that.

    >
    >
    > Of course it can, for exactly the same reason that I can: in that
    > context, p is a non-variable-sized array, which has constant size - 56,
    > to be precise. sizeof p is therefore 56, and sizeof p/2 is 28, and 28
    > _must_ convert correctly to int.


    Ah. OK. I might be as dumb as lint sometimes, but at least I can learn. ;)

    (In other words, it's bleedingly obvious from the code and if lint can't
    pick it up, it's broken. Which seems to be a recurrent theme here.)

    >
    >
    >
    >>>>Ben.c:10:9: Function strchr shadows outer declaration
    >>>> An outer declaration is shadowed by the local declaration.
    >>>
    >>>Where, pray, is this "outer declaration" to be found?

    >>
    >>The '#include'd header file?

    >
    >
    > There _is_ no header file in that code.


    I was trying to make lint sound ... not obviously broken.

    >
    >
    >>The old-style implicit declaration of everything returning an int?

    >
    >
    > That doesn't exist unless the function is called without an explicit
    > declaration. Which it isn't.


    See above.

    >
    >
    >>>>Ben.c:12:10: Test expression for while not boolean, type char: *q
    >>>> Test expression type is not boolean.
    >>>
    >>>Yer_what_?

    >>
    >>Here's where lint is a bit too pedantic

    >
    >
    > No, it's talking out of its hat. The control expression of a while loop
    > need not be "boolean" at all, whatever lint, in its poor addled
    > imagination, thinks a "boolean" type is in pre-99 C.


    Which is why I found this specific warning absurd. It's confusing
    because it's wrong, in other words.

    Of course, having a boolean context without having a boolean type is
    also a bit odd. C99 fixes this, but it's been a quirk of C for a long time.

    >
    >
    >>C acts like it has a boolean type sometimes,

    >
    >
    > Not unless you're using C99.


    Well, I should have phrased better: A context means the value is coerced
    implicitly to some type. What type would it be coerced into in a boolean
    context? A boolean type, which conveniently does not exist in any C
    version earlier than C99.

    In other words, see above.

    >>lint doesn't know, and can't be made to know, that things other than
    >>boolean-returning relational expressions (such as (a > 5) or (f <= 12))
    >>can meaningfully be used in a boolean context.

    >
    >
    > In other words, lint is incorrigibly broken. Such uses are perfectly
    > correct in C, and flagging them as wrong is simply not correct.


    Here I do agree with you now, whereas I wouldn't have when I posted the
    original article. lint insisting on things the C Standard doesn't insist
    on (*explicitly* doesn't insist on, in fact) is a fault of lint.

    >
    >
    >>>>Ben.c:14:12: Variable strchr used before definition
    >>>> An rvalue is used that may not be initialized to a value on some execution
    >>>> path.
    >>>>Ben.c:17:7: Variable putchar used before definition
    >>>
    >>>Erm... boggle.

    >>
    >>lint's stupid sometimes.

    >
    >
    > Understatement of the year award granted on January 2nd already.


    I'd like to thank the Academy.

    >
    >
    >>>>Ben.c:17:7: Return value (type int) ignored: putchar(p)
    >>>> Result returned by function call is not used.
    >>>
    >>>Gosh. Lint really _is_ prehistoric, isn't it?

    >>
    >>According to K&R2, putchar() does indeed return an int.

    >
    >
    > Yes. And according to the same K&R, there is no need to use the return
    > value of every single expression. I note, for example, that lint does
    > not complain about the various assignment statements, whose results are
    > ignored as well.


    Heh. Good one ... lint should be complaining left and right about
    boolean values being thrown away. Maybe then /everyone/ will decide it's
    Not Worth It.

    >
    >
    >>I suspect a cast
    >>to void would silence lint, but it's hardly worth it, is it?

    >
    >
    > My point exactly. I haven't seen lint-shutting-up casts for ages, and it
    > is indeed hardly worth the trouble to deface your code so badly if you
    > can, with much less effort, throw the bloody dinosaur out the window and
    > use a proper error-checking compiler.


    I concur, even as I pass my code through a lint clone. gcc with -Wall,
    -ansi, and -pedantic does wonderful things, but it's just not the same
    if I can't decide to ignore warnings instead of acting on them, now is
    it? :)
    August Derleth, Jan 7, 2004
    #18
  19. Arthur J. O'Dwyer wrote:

    > On Mon, 5 Jan 2004, August Derleth wrote:
    >
    >>Richard Bos wrote:
    >>
    >>>Jean-Michel Collard <> wrote:
    >>>
    >>>>Ben.c:12:10: Test expression for while not boolean, type char: *q
    >>>> Test expression type is not boolean.
    >>>
    >>>Yer_what_?

    >>
    >>Here's where lint is a bit too pedantic (well, here's a single instance
    >>out of possibly thousands ;)): C acts like it has a boolean type
    >>sometimes, and it certainly has a boolean context. lint doesn't know,
    >>and can't be made to know, that things other than boolean-returning
    >>relational expressions (such as (a > 5) or (f <= 12)) can meaningfully
    >>be used in a boolean context.
    >>
    >>IMNSHO, lint here goes from pedantic to incorrect. Even the earliest
    >>versions of C would gleefully, and conformantly, accept things that
    >>aren't strictly booleans where it imposes a boolean context. For lint to
    >>complain about such things has never been helpful.

    >
    >
    > It might be helpful in cases like
    >
    > if (a=b)


    It would still be wrong, though. See Richard's post for details, but the
    upshot is that any scalar value can be coerced via a boolean context
    into a form usable by any of the conditional statements. Insisting on a
    boolean type, which was quite mythical until C99, is wrong.

    What lint should do is shut up about 90% of the cases and correctly warn
    about cases like yours with a correct statement, such as `assignment
    used where test expected' or some such.

    >
    > The problems are (1) lint uses the word "boolean" like the programmer
    > is supposed to know what it means, and which "types" are "boolean"
    > enough for lint -- but C90 doesn't have boolean types -- and (2) lint
    > should really know about common idioms like 'if (*q)'. It makes a
    > large bit of sense to warn about 'if (a+b)' or the like, for the sake
    > of lint-ness, but lint should know better than to complain in this
    > case.


    In other words, lint should not be broken.

    >
    >
    >
    >>>>Ben.c:17:7: Return value (type int) ignored: putchar(p)
    >>>> Result returned by function call is not used.
    >>>
    >>>Gosh. Lint really _is_ prehistoric, isn't it?

    >>
    >>According to K&R2, putchar() does indeed return an int. I suspect a cast
    >>to void would silence lint, but it's hardly worth it, is it?

    >
    >
    > Some old code, and some overly-portable code, does use casts to
    > void. We even get questions about (void)printf here occasionally.
    > I can only assume there's some way to switch off this warning in
    > modern lints; it would get really obnoxious if you tried to lint a
    > big source file.


    As Richard said, it's not wrong to ignore the value of anything,
    including a function call. Otherwise, we'd need to wrap a conditional
    statement around every assignment statement.

    >
    >
    >>[OT]
    >>I use splint, a lint-a-like, myself, and splint gives you the warning,
    >>the explanation, and the argument you can pass to splint to make it shut
    >>up about the damned warning. I usually invoke splint with no flags once,
    >>then with a few to weed out the more egregiously inane whinings.

    >
    >
    > Excellent. I wish gcc would do this too, for its warnings. It
    > seems like a very nice feature.


    It's the only way I'll use a lint-like program at all, especially now.
    August Derleth, Jan 7, 2004
    #19
  20. Ben Pfaff wrote:

    > August Derleth <> writes:
    >
    >
    >>lint's stupid sometimes.

    >
    >
    > lint is stupid to the point of uselessness. As just one example,
    > at least one variety of lint emits a warning for the following:
    > long x = 0;
    > saying that the initializer is not of the proper type.


    You could say
    long x = 0L;

    Or you could stop using lint.

    Whichever.

    (I'd opt for the second, assuming I have a reasonably good compiler.)
    August Derleth, Jan 7, 2004
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Horace Nunley

    why why why does function not work

    Horace Nunley, Sep 27, 2006, in forum: ASP .Net
    Replies:
    1
    Views:
    448
    =?Utf-8?B?UGV0ZXIgQnJvbWJlcmcgW0MjIE1WUF0=?=
    Sep 27, 2006
  2. Mr. SweatyFinger

    why why why why why

    Mr. SweatyFinger, Nov 28, 2006, in forum: ASP .Net
    Replies:
    4
    Views:
    858
    Mark Rae
    Dec 21, 2006
  3. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,756
    Smokey Grindel
    Dec 2, 2006
  4. rp
    Replies:
    1
    Views:
    494
    red floyd
    Nov 10, 2011
  5. Srijayanth Sridhar
    Replies:
    19
    Views:
    596
    David A. Black
    Jul 2, 2008
Loading...

Share This Page