strtod valiation - beat it up

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Bob Nelson

    strtod valiation - beat it up

    Fellow C pushers:

    Deliberately avoiding a look at Jack Klein's bulletproof code for a
    robust use of strtol(), I respectfully submit the following for review
    and vigorous critique, desiring unapologetic pedantry (in the *very*
    best sense of that word).

    In the way of background, I may as well be a C newbie since the nature
    of my job has not involved day to day use of the language for maybe a
    decade. Although I am entering my ``golden years'', I decided to put
    aside my AARP magazine and try to regain my youth^wC skills by
    re-reading some good books, the clc-faq, n1256.pdf and getting some
    hearty laughs from reading you know who.

    No...I don't plan to post such toy code on a regular basis but feedback
    from the experts in c.l.c may help me get my shaky C legs back.

    All comments were elided for brevity in this attempt to ``convert''
    argument(s) to double(s) with a fair amount of validation:

    #include <ctype.h>
    #include <errno.h>
    #include <math.h>
    #include <stdio.h>
    #include <stdlib.h>

    static int is_valid_double (const char *s, const char *endptr,
    double result, int save_errno, char **what)
    {
    int status = 0;

    if(result == 0 && save_errno == ERANGE)
    *what = "underflow" ;
    else if((result == HUGE_VAL || result == -HUGE_VAL) &&
    save_errno == ERANGE)
    *what = "overflow";
    else if(s == endptr)
    *what = "no characters in subject sequence";
    else {
    int is_recognized = 1;

    for(; *endptr; ++endptr) {
    if(!isspace(*en dptr)) {
    is_recognized = 0;
    break;
    }
    }

    if(is_recognize d)
    status = 1;
    else
    *what = "unrecogniz ed character(s) in final string";
    }

    return status;
    }

    static void maybe_convert_t o_double(const char *s)
    {
    double result;
    char *endptr, *what;
    const char *indication = "failed";
    int save_errno, valid;

    result = strtod(s, &endptr);
    save_errno = errno;

    if((valid = is_valid_double (s, endptr, result, save_errno, &what)) != 0)
    indication = "successful ";

    printf("result: %g, conversion %s", result, indication);

    if(valid)
    putchar('\n');
    else
    printf(" due to %s\n", what);
    }

    int main(int argc, char **argv)
    {
    int i;

    for(i = 1; i < argc; ++i)
    maybe_convert_t o_double(argv[i]);

    return EXIT_SUCCESS;
    }
  • Eric Sosman

    #2
    Re: strtod valiation - beat it up

    Bob Nelson wrote:
    Fellow C pushers:
    >
    Deliberately avoiding a look at Jack Klein's bulletproof code for a
    robust use of strtol(), I respectfully submit the following for review
    and vigorous critique, desiring unapologetic pedantry (in the *very*
    best sense of that word).
    >
    In the way of background, I may as well be a C newbie since the nature
    of my job has not involved day to day use of the language for maybe a
    decade. Although I am entering my ``golden years'', I decided to put
    aside my AARP magazine and try to regain my youth^wC skills by
    re-reading some good books, the clc-faq, n1256.pdf and getting some
    hearty laughs from reading you know who.
    >
    No...I don't plan to post such toy code on a regular basis but feedback
    from the experts in c.l.c may help me get my shaky C legs back.
    >
    All comments were elided for brevity in this attempt to ``convert''
    argument(s) to double(s) with a fair amount of validation:
    >
    #include <ctype.h>
    #include <errno.h>
    #include <math.h>
    #include <stdio.h>
    #include <stdlib.h>
    >
    static int is_valid_double (const char *s, const char *endptr,
    double result, int save_errno, char **what)
    {
    int status = 0;
    >
    if(result == 0 && save_errno == ERANGE)
    *what = "underflow" ;
    And what if errno just happened to be equal to ERANGE
    before the strtod() call? Hmmm?
    else if((result == HUGE_VAL || result == -HUGE_VAL) &&
    save_errno == ERANGE)
    As above. Also, what if HUGE_VAL is an infinity?
    *what = "overflow";
    else if(s == endptr)
    *what = "no characters in subject sequence";
    else {
    int is_recognized = 1;
    >
    for(; *endptr; ++endptr) {
    if(!isspace(*en dptr)) {
    Potential for undefined behavior if `char' is signed.
    This is one of those relatively rare cases where a cast is
    obligatory.
    is_recognized = 0;
    break;
    }
    }
    >
    if(is_recognize d)
    status = 1;
    else
    *what = "unrecogniz ed character(s) in final string";
    }
    >
    return status;
    }
    >
    static void maybe_convert_t o_double(const char *s)
    {
    double result;
    char *endptr, *what;
    const char *indication = "failed";
    int save_errno, valid;
    >
    result = strtod(s, &endptr);
    save_errno = errno;
    >
    if((valid = is_valid_double (s, endptr, result, save_errno, &what)) != 0)
    indication = "successful ";
    >
    printf("result: %g, conversion %s", result, indication);
    >
    if(valid)
    putchar('\n');
    else
    printf(" due to %s\n", what);
    }
    >
    int main(int argc, char **argv)
    {
    int i;
    >
    for(i = 1; i < argc; ++i)
    maybe_convert_t o_double(argv[i]);
    >
    return EXIT_SUCCESS;
    }
    A few problems, and a style that seems over-ornamented, but
    not too bad for someone in his dotage. ;-)

    --
    Eric Sosman
    esosman@ieee-dot-org.invalid

    Comment

    • Bob Nelson

      #3
      Re: strtod valiation - beat it up

      Eric Sosman wrote:
      Bob Nelson wrote:
      >>
      >[...lossy compression...]
      >>
      > if(result == 0 && save_errno == ERANGE)
      > *what = "underflow" ;
      >
      And what if errno just happened to be equal to ERANGE
      before the strtod() call? Hmmm?
      The dog ate the ``errno = 0;'' I had before the call to ``strtod()''.
      Honestly. :-)
      > for(; *endptr; ++endptr) {
      > if(!isspace(*en dptr)) {
      >
      Potential for undefined behavior if `char' is signed.
      This is one of those relatively rare cases where a cast is
      obligatory.
      I can't blame the dog for that botch. Back in the day when I was somewhat
      more accomplished with C, a cast to ``(unsigned char)'' in this context
      used to come automatically. I appreciate you pointing this out.
      A few problems, and a style that seems over-ornamented, but
      not too bad for someone in his dotage. ;-)
      I greatly appreciate you taking this time to look this over, Eric and I look
      forward to others sparring with the little exercise. Over-ornamented? Well,
      you ought to see the comments! Gargoyles and gingerbread a plenty.

      Good night all, time for my prune juice. :-)

      Comment

      • Richard

        #4
        Re: strtod valiation - beat it up

        Bob Nelson <bnelson@nelson be.comwrites:
        Fellow C pushers:
        >
        Deliberately avoiding a look at Jack Klein's bulletproof code for a
        robust use of strtol(), I respectfully submit the following for review
        and vigorous critique, desiring unapologetic pedantry (in the *very*
        best sense of that word).
        >
        In the way of background, I may as well be a C newbie since the nature
        of my job has not involved day to day use of the language for maybe a
        decade. Although I am entering my ``golden years'', I decided to put
        aside my AARP magazine and try to regain my youth^wC skills by
        re-reading some good books, the clc-faq, n1256.pdf and getting some
        hearty laughs from reading you know who.
        Uh oh. We have someone who is clearly "in love" with Dan Pop. This will
        be a very unhealthy addition to the regs and pedants here.
        No...I don't plan to post such toy code on a regular basis but feedback
        from the experts in c.l.c may help me get my shaky C legs back.
        Yuck! Put it away! :-;

        *snip*

        Other then Eric's comments I would add that it seems rather too heavy
        for such a potentially simply thing. One of the questions would be :
        where do the inputs come from? Are they not guarenteed to be a certain
        form? And if not, what makes you think that random garbage parameters
        wont be mistakenly interpreted as doubles (event though they are,
        luckily, doubles...).

        Comment

        • Bob Nelson

          #5
          Re: strtod valiation - beat it up

          On Fri, 13 Jun 2008 12:46:07 +0200, Richard wrote:
          Bob Nelson <bnelson@nelson be.comwrites:
          >
          >Fellow C pushers:
          >>
          >Deliberately avoiding a look at Jack Klein's bulletproof code for a
          >robust use of strtol(), I respectfully submit the following for review
          >and vigorous critique, desiring unapologetic pedantry (in the *very*
          >best sense of that word).
          >>
          >In the way of background, I may as well be a C newbie since the nature
          >of my job has not involved day to day use of the language for maybe a
          >decade. Although I am entering my ``golden years'', I decided to put
          >aside my AARP magazine and try to regain my youth^wC skills by
          >re-reading some good books, the clc-faq, n1256.pdf and getting some
          >hearty laughs from reading you know who.
          >
          Uh oh. We have someone who is clearly "in love" with Dan Pop. [...]
          Hardly. Although a person's certainly character can't be judged by what's
          posted to a newsgroup, my impression of Dan Pop (based **ONLY** AND
          **SOLELY** [extra emphasis intended] on what I observed here in c.l.c over
          some 18 years) is that he's an arrogant loutish bully. And that's being
          charitable.

          On the other hand, he knew (and presumably still does) the C language and
          often explained nuances of the language well. And that's all that counts
          in the context of this newsgroup.

          By way of analogy, the NFL (National Football League, a professional
          sports organization in the United States of America) inducts players into
          their Canton, OH ``Hall of Fame'' based strictly upon on-field
          accomplishments . Misanthropic and thuggish behavior, of which there is
          plenty in that sport, is not part of the criteria for being enshrined.

          Within this newsgroup, I think we must partition the personality
          from the prowess. And, let's be thankful for the too-rare near-saints like
          Lawrence Kirby, Chris Torek and and handful of others who combine deep
          knowledge of C with patient kindness.

          Comment

          Working...