Using strtod

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

    #16
    Re: Using strtod

    On Feb 19, 12:15 pm, "Harald van Dijk" <true...@gmail. comwrote:
    coder wrote:
    On Feb 18, 11:54 pm, "Harald van Dijk" <true...@gmail. comwrote:
    coder wrote:
    On Feb 18, 10:47 pm, "Harald van Dijk" <true...@gmail. comwrote:
    coder wrote:
    <snip>
    >
    Thanks for the reply, Harald.
    >
    You are allowed to do this as long as you bypass any possible macro
    definition of strtod:
    value = (strtod) (p, &p);
    >
    I didn't get that. Can you please explain a little more?
    >
    strtod(p, &p) both reads from p and writes to p. If you're using a
    function, there's no problem, because the reading from p is guaranteed
    to take place before any write. If you're using a macro, the macro is
    allowed to write to p before reading its original value.
    >
    I still don't understand fully. Can you (or someone else) please give
    an example to illustrate this?
    >
    Please excuse me for my ignorance.
    >
    Let's use strtol as another example for simplicity, and let's say the
    compiler supports GCC-style statement-expressions and C++-style
    references as extensions. Then, strtol might be implemented as
    something similar to
    >
    #define strtol(n, end, base) \
    ({ \
    const char * const &__n = n; \
    char * &__end = *end; \
    int const &__base = base; \
    for (__end = __n; *__end != '\0'; __end++) \
    if (!isspace(*__en d)) \
    break; \
    for (; *__end != '\0'; __end++) \
    if (!isbasedigit(* __end, __base)) \
    break; \
    strntol(__n, __end - __n, __base); \
    })
    >
    Consider what would happen when end == &n: the final call to strntol
    (a non-standard helper function) would pass unexpected arguments.
    >
    (Note: this example would need some editing to even be a potential
    valid implementation of strtol, but the basic idea stands.)
    Ok, so the basic idea is that a macro can access variables directly,
    whereas variables are passed by value to functions. Is that right?

    Comment

    • =?utf-8?B?SGFyYWxkIHZhbiBExLNr?=

      #17
      Re: Using strtod

      coder wrote:
      On Feb 19, 12:15 pm, "Harald van Dijk" <true...@gmail. comwrote:
      coder wrote:
      On Feb 18, 11:54 pm, "Harald van Dijk" <true...@gmail. comwrote:
      coder wrote:
      On Feb 18, 10:47 pm, "Harald van Dijk" <true...@gmail. comwrote:
      coder wrote:
      <snip>
      Thanks for the reply, Harald.
      You are allowed to do this as long as you bypass any possible macro
      definition of strtod:
      value = (strtod) (p, &p);
      I didn't get that. Can you please explain a little more?
      strtod(p, &p) both reads from p and writes to p. If you're using a
      function, there's no problem, because the reading from p is guaranteed
      to take place before any write. If you're using a macro, the macro is
      allowed to write to p before reading its original value.
      I still don't understand fully. Can you (or someone else) please give
      an example to illustrate this?
      Please excuse me for my ignorance.
      Let's use strtol as another example for simplicity, and let's say the
      compiler supports GCC-style statement-expressions and C++-style
      references as extensions. Then, strtol might be implemented as
      something similar to

      #define strtol(n, end, base) \
      ({ \
      const char * const &__n = n; \
      char * &__end = *end; \
      int const &__base = base; \
      for (__end = __n; *__end != '\0'; __end++) \
      if (!isspace(*__en d)) \
      break; \
      for (; *__end != '\0'; __end++) \
      if (!isbasedigit(* __end, __base)) \
      break; \
      strntol(__n, __end - __n, __base); \
      })

      Consider what would happen when end == &n: the final call to strntol
      (a non-standard helper function) would pass unexpected arguments.

      (Note: this example would need some editing to even be a potential
      valid implementation of strtol, but the basic idea stands.)
      >
      Ok, so the basic idea is that a macro can access variables directly,
      whereas variables are passed by value to functions. Is that right?
      That may be a bit oversimplified, but it's the basic idea, yes.

      Comment

      • coder

        #18
        Re: Using strtod

        On Feb 19, 1:54 pm, "Harald van Dijk" <true...@gmail. comwrote:
        coder wrote:
        On Feb 19, 12:15 pm, "Harald van Dijk" <true...@gmail. comwrote:
        coder wrote:
        On Feb 18, 11:54 pm, "Harald van Dijk" <true...@gmail. comwrote:
        coder wrote:
        On Feb 18, 10:47 pm, "Harald van Dijk" <true...@gmail. comwrote:
        coder wrote:
        <snip>
        >
        Thanks for the reply, Harald.
        >
        You are allowed to do this as long as you bypass any possiblemacro
        definition of strtod:
        value = (strtod) (p, &p);
        >
        I didn't get that. Can you please explain a little more?
        >
        strtod(p, &p) both reads from p and writes to p. If you're using a
        function, there's no problem, because the reading from p is guaranteed
        to take place before any write. If you're using a macro, the macro is
        allowed to write to p before reading its original value.
        >
        I still don't understand fully. Can you (or someone else) please give
        an example to illustrate this?
        >
        Please excuse me for my ignorance.
        >
        Let's use strtol as another example for simplicity, and let's say the
        compiler supports GCC-style statement-expressions and C++-style
        references as extensions. Then, strtol might be implemented as
        something similar to
        >
        #define strtol(n, end, base) \
        ({ \
        const char * const &__n = n; \
        char * &__end = *end; \
        int const &__base = base; \
        for (__end = __n; *__end != '\0'; __end++) \
        if (!isspace(*__en d)) \
        break; \
        for (; *__end != '\0'; __end++) \
        if (!isbasedigit(* __end, __base)) \
        break; \
        strntol(__n, __end - __n, __base); \
        })
        >
        Consider what would happen when end == &n: the final call to strntol
        (a non-standard helper function) would pass unexpected arguments.
        >
        (Note: this example would need some editing to even be a potential
        valid implementation of strtol, but the basic idea stands.)
        >
        Ok, so the basic idea is that a macro can access variables directly,
        whereas variables are passed by value to functions. Is that right?
        >
        That may be a bit oversimplified, but it's the basic idea, yes.
        Thanks for the information, Harald.

        Comment

        • CBFalconer

          #19
          Re: Using strtod

          Harald van D?k wrote:
          CBFalconer wrote:
          >Gordon Burditt wrote:
          >>>
          >>>>>>You are allowed to do this as long as you bypass any possible
          >>>>>>macro definition of strtod:
          >>>>>>>
          >>>>>>value = (strtod) (p, &p);
          >>>>>>
          >>>>>I didn't get that. Can you please explain a little more?
          >>>>>
          >>>>strtod(p, &p) both reads from p and writes to p. If you're using
          >>>>a function, there's no problem, because the reading from p is
          >>>>guarantee d to take place before any write. If you're using a
          >>>>macro, the macro is allowed to write to p before reading its
          >>>>original value.
          >>>>
          >>>Chapter and verse, please.
          >>>>
          >>>There is nothing at all in the standard that states that strtod()
          >>>or the other related strto... functions do not write to the
          >>>pointer addressed by their second argument until after they have
          >>>finished all use of the first argument.
          >>>
          >... snip ...
          >>>>
          >>>There is absolutely nothing at all preventing an implementation
          >>>from providing a strtod() function like this:
          >>>>
          >>>double strtod(const char * restrict nptr, char ** restrict endptr)
          >>>{
          >>> double result = 0.0;
          >>> *endptr = NULL;
          >>>
          >>The above statement cannot mess up nptr nor what it points at.
          >>
          >However something like (never mind if it is an accurate strtod)
          >>
          >double strtod(const char *restrict nptr, char* *restrict endptr)
          >{
          > if (*nptr) {
          > do {
          > **nptr = '0';
          > } while (*(*nptr)++ != '\0');
          > }
          > return 0.0;
          >}
          >>
          >can foul everything up nicely as a result of ignoring restrict.
          >
          How can you assign to **nptr when nptr is a pointer to a character?
          Woops. Replace nptr with endptr in the above fragment body.

          --
          <http://www.cs.auckland .ac.nz/~pgut001/pubs/vista_cost.txt>
          <http://www.securityfoc us.com/columnists/423>

          "A man who is right every time is not likely to do very much."
          -- Francis Crick, co-discover of DNA
          "There is nothing more amazing than stupidity in action."
          -- Thomas Matthews


          Comment

          Working...