strtol const-ness problem

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

    #1

    strtol const-ness problem

    The signature for strtol is:

    strtol( const char*, char**, int)

    So.. if we start with a passed "const char*" (pointer to const char),
    then we can't create a non-const char pointer pointer to that const
    char pointer as in:

    void func( const char* a )
    {
    // ERROR: invalid conversion from `const char**' to `char**'
    char** pa = &a;
    int i = strtol( a, pa, 10 );
    }

    And here is another way of saying the same thing without temporary
    variables.

    void func( const char* a )
    {
    // ERROR: invalid conversion from `const char**' to `char**'
    // ERROR: initializing argument 2 of `long int strtol...
    int i = strtol( a, &a, 10 );

    }

    But you CAN do:

    void func( const char* a )
    {
    int i = strtol( a, (char**)&a, 10 ); // OK
    }

    AND you can also do this:

    void func( const char* a )
    {
    char* tmp;
    int i = strtol( a, &tmp, 10 ); // OK
    a = tmp;
    }

    This indirectly allows us to modify the original const char* a through
    the new pointer tmp since tmp will point into the character array a. It
    doesn't involve a hard cast, but it seems just as dangerous or even
    more so because it's not obvious what just happened. The calling
    function could see a change in the string pointed to by a, even though
    it's passed as pointer to const.

    Can someone help me figure out why this is OK?

  • Heinz Ozwirk

    #2
    Re: strtol const-ness problem

    "dstevel" <google@lakepag e.comschrieb im Newsbeitrag
    news:1155371593 .231586.237380@ m73g2000cwd.goo glegroups.com.. .
    The signature for strtol is:
    >
    strtol( const char*, char**, int)
    >
    So.. if we start with a passed "const char*" (pointer to const char),
    then we can't create a non-const char pointer pointer to that const
    char pointer ...
    In my opinion, this to be a bug in the standard. For many other functions
    inherited from C, the standard has defined two functions with const and
    non-const arguements, but strtol seems to be missing in that group. There
    should better be two different overloads:

    long strtol(char*, char**, int)
    long strtol(char const*, char const**, long)

    Perhaps you should post your message to comp.std.c++.

    [...]
    Can someone help me figure out why this is OK?
    I'm curious to see if anyone could...

    Heinz

    Comment

    • wittempj@hotmail.com

      #3
      Re: strtol const-ness problem

      not a direct answer, but I would consider what the faq says about
      converting a string to a number:


      dstevel wrote:
      The signature for strtol is:
      >
      strtol( const char*, char**, int)
      >
      So.. if we start with a passed "const char*" (pointer to const char),
      then we can't create a non-const char pointer pointer to that const
      char pointer as in:
      >
      void func( const char* a )
      {
      // ERROR: invalid conversion from `const char**' to `char**'
      char** pa = &a;
      int i = strtol( a, pa, 10 );
      }
      >
      And here is another way of saying the same thing without temporary
      variables.
      >
      void func( const char* a )
      {
      // ERROR: invalid conversion from `const char**' to `char**'
      // ERROR: initializing argument 2 of `long int strtol...
      int i = strtol( a, &a, 10 );
      >
      }
      >
      But you CAN do:
      >
      void func( const char* a )
      {
      int i = strtol( a, (char**)&a, 10 ); // OK
      }
      >
      AND you can also do this:
      >
      void func( const char* a )
      {
      char* tmp;
      int i = strtol( a, &tmp, 10 ); // OK
      a = tmp;
      }
      >
      This indirectly allows us to modify the original const char* a through
      the new pointer tmp since tmp will point into the character array a. It
      doesn't involve a hard cast, but it seems just as dangerous or even
      more so because it's not obvious what just happened. The calling
      function could see a change in the string pointed to by a, even though
      it's passed as pointer to const.
      >
      Can someone help me figure out why this is OK?

      Comment

      • dstevel

        #4
        Re: strtol const-ness problem

        Thanks for the link. The nice part about strtol compared with all of
        those convert functions is that strtol only converts the number at the
        first portion of the string, then returnsa pointer to the rest of the
        string in the char** you provide to it.

        I'm using it to pick out the numbers in a long string that contains a
        mix of letters and numbers like:

        "ABC1234/CDEF44/XYZ/275B"

        and my program picks out 1234, 44, 275

        It goes through a string 1 character at a time, and if it finds a digit
        it called strtol on the current character to get the full number. Then
        it continues examining the non-digits at the point where strtol
        indicates the number ended. I don't know that any of those convert
        functions do that. They seem to expect the full string to be a valid
        number like "12345" = 12345.




        wittempj@hotmai l.com wrote:
        not a direct answer, but I would consider what the faq says about
        converting a string to a number:

        >
        dstevel wrote:
        The signature for strtol is:

        strtol( const char*, char**, int)

        So.. if we start with a passed "const char*" (pointer to const char),
        then we can't create a non-const char pointer pointer to that const
        char pointer as in:

        void func( const char* a )
        {
        // ERROR: invalid conversion from `const char**' to `char**'
        char** pa = &a;
        int i = strtol( a, pa, 10 );
        }

        And here is another way of saying the same thing without temporary
        variables.

        void func( const char* a )
        {
        // ERROR: invalid conversion from `const char**' to `char**'
        // ERROR: initializing argument 2 of `long int strtol...
        int i = strtol( a, &a, 10 );

        }

        But you CAN do:

        void func( const char* a )
        {
        int i = strtol( a, (char**)&a, 10 ); // OK
        }

        AND you can also do this:

        void func( const char* a )
        {
        char* tmp;
        int i = strtol( a, &tmp, 10 ); // OK
        a = tmp;
        }

        This indirectly allows us to modify the original const char* a through
        the new pointer tmp since tmp will point into the character array a. It
        doesn't involve a hard cast, but it seems just as dangerous or even
        more so because it's not obvious what just happened. The calling
        function could see a change in the string pointed to by a, even though
        it's passed as pointer to const.

        Can someone help me figure out why this is OK?

        Comment

        Working...