CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 2 of 3 FirstFirst 123 LastLast
Results 16 to 30 of 33
  1. #16
    Join Date
    Oct 2009
    Posts
    577

    Smile Re: A question regarding *s++

    Quote Originally Posted by monarch_dodra View Post
    Maybe you are confusing evaluation order?

    Regardless of type, when you write:

    Code:
    *p++ = *q++
    Both p++ and q++ are evaluated first (but in undefined relative order).

    Once this is done, operator= is called on the return values of p++ and q++, ie, the old values of p and q. (making it look like the assignment took place before increment)

    There is no special magic or rules that applies only to PODs that do the assignments first, and then increments the values of p or q.

    ...

    Either that, or I seem to not understand what you are saying. Your example (rewritten since incomplete) seems to work correctly:

    Code:
    #include <iostream>
    #include <string>
    
    int main()
    {
        char pArray[20] = { '\0' };
        char* p = pArray;
        std::string helloStr = "Hello";
    
        //force the null terminator into string //Undefined behavior, but defined in practice
        helloStr.c_str();
    
        std::string::iterator q = helloStr.begin();
        while (*p++ = *q++); //note that this reads string.end(), but should point '\0'. May crash in ranged debug
    
        std::cout << pArray << std::endl;
    }
    Code:
    output: Hello
    Was this your full example?

    Regards,
    No, it was from my memories ;-)

    Here is the code that compiles:

    Code:
    #include <iostream>
    int main()
    {
        char * q = "Hello";
        char buf[20] = { '\0' };
        char * p = buf;
        while (*p++ = *q++);
        std::cout << buf << std::endl;
        return 0;
    }
    If incrementation would happen before assignment the p[0] would not be set correctly.

    I will add the string class example soonly.

    Regards, Alex

  2. #17
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: A question regarding *s++

    Quote Originally Posted by itsmeandnobodyelse View Post
    If incrementation would happen before assignment the p[0] would not be set correctly.
    Sure it would, given the post-increment semantics which are at the heart of what we're discussing.

  3. #18
    Join Date
    Oct 2009
    Posts
    577

    Smile Re: A question regarding *s++

    Here the full sample

    Code:
    #include<iostream>
    
    class String
    {
        char * ps;
        int    siz;
        int    len;
    public:
        String(const char * psz)
        {
           siz = strlen(psz)+1;
           ps = new char[siz];
           strcpy(ps, psz);
        }
        ~String() { delete []ps; }
        const char * c_str() { return ps; }
        friend class StringIterator;
    };
    
    class StringIterator
    {
        int pos;
        String * s;
    public:
        StringIterator(String & str) : s(&str), pos(0) {}
        char & operator*() { return s->ps[pos]; }
        StringIterator& operator++(int)
        {
            pos++;
            return *this;
        }
    };
    int main()
    {
        char * q = "Hello";
        char buf[20] = { '\0' };
        char * p = buf;
        while (*p++ = *q++);
        std::cout << buf << std::endl;
    
        String s("World");
        String t("              ");
        StringIterator i(s);
        StringIterator j(t);
        while (*j++ = *i++);
    
        std::cout << t.c_str() << std::endl;
        return 0;
    }
    And output is

    Hello
    orld

    Regards, Alex

    P.S.
    I don't think the above is a real problem. However, it was that what invoked me to not using post-increment on class types anymore.

  4. #19
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: A question regarding *s++

    Quote Originally Posted by Lindley View Post
    Sure it would, given the post-increment semantics which are at the heart of what we're discussing.
    Quote Originally Posted by itsmeandnobodyelse View Post
    StringIterator& operator++(int)
    {
    pos++;
    return *this;
    }
    The real problem is that you implemented post-increment as pre-increment, breaking standard conventions and assumptions.

    I'm pretty sure 4 or 5 people will tell you the same in a 5 minute time span.
    Is your question related to IO?
    Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

  5. #20
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: A question regarding *s++

    Quote Originally Posted by itsmeandnobodyelse View Post
    Here the full sample
    A correct implementation of post-increment would be:
    Code:
        StringIterator operator++(int)
        {
            StringIterator copy(*this);
            pos++;
            return copy;
        }
    This would give the correct result. However, the expense of the copy is the reason why post-increment is sometimes slower.

  6. #21
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: A question regarding *s++

    Quote Originally Posted by Lindley View Post
    A correct implementation of post-increment would be:
    Code:
        StringIterator operator++(int)
        {
            StringIterator copy(*this);
            pos++;
            return copy;
        }
    This would give the correct result. However, the expense of the copy is the reason why post-increment is sometimes slower.
    Ok, looking at that code makes it clear why the compiler couldn't optimize away the additional overhead (under normal circumstances), even if I don't use the returned temporary object.

    But could it do that if the implementation of the operator would be inlined?

  7. #22
    Join Date
    May 2007
    Location
    Scotland
    Posts
    1,164

    Re: A question regarding *s++

    Personally, I would replace the following incorrectly implemented post-increment operator:

    Code:
    StringIterator& operator++(int)
    {
      pos++;
      return *this;
    }
    with

    Code:
    //pre-increment: ++i
    StringIterator& operator++()
    {
      ++pos;
      return *this;
    }
    
    //post-increment: i++
    StringIterator operator++()
    {
      StringIterator orig(*this);
      ++(*this);
      return orig;
    }
    EDIT:
    But I would like to ask the question... why are you implementing a string type anyway? Why not use std::string?
    Last edited by PredicateNormative; August 3rd, 2010 at 09:36 AM.

  8. #23
    Join Date
    Oct 2009
    Posts
    577

    Thumbs up Re: A question regarding *s++

    Quote Originally Posted by monarch_dodra View Post
    The real problem is that you implemented post-increment as pre-increment, breaking standard conventions and assumptions.

    I'm pretty sure 4 or 5 people will tell you the same in a 5 minute time span.
    I thank you very much for pointing out my error. It was a very old issue (maybe 16 years old) and I am very glad that I now know the solution.

    But I would like to ask the question... why are you implementing a string type anyway? Why not use std::string?
    I am using std::string since 2003. The various string classes I made are all older than 10 years where STL wasn't available for all compilers or were not allowed to be used in projects.

    Private string classes can have a much better functionality than std::string. Especially for streaming, editable substrings and codeset support. The (only?) disadvantage is that they were not available with the compiler and must be installed (and be allowed) at each new platform.

    Regards, Alex

  9. #24
    Join Date
    May 2002
    Location
    Lindenhurst, NY
    Posts
    867

    Re: A question regarding *s++

    Quote Originally Posted by itsmeandnobodyelse View Post
    The (only?) disadvantage is that they were not available with the compiler and must be installed (and be allowed) at each new platform.
    Another disadvantage is that std::string is standard whereas your custom string class is not. A new team member wouldn't have to spend any time learning the 'Alex String Library'. He/she could instead be using a well documented, well tested, well known library. If he/she doesn't already know std::string, he/she could learn it & know that the knowledge will still be relevant if he/she changed companies (unlike effort spent to learn alex::string). When there's a bug they can be 99% sure its not a bug in the string class (although there seems to be no shortage of programmers that blame the compiler). They could post questions on programming forums about how to use std::string but not alex::string.

  10. #25
    Join Date
    Oct 2009
    Posts
    577

    Smile Re: A question regarding *s++

    Quote Originally Posted by Martin O View Post
    Another disadvantage is that std::string is standard whereas your custom string class is not. A new team member wouldn't have to spend any time learning the 'Alex String Library'. He/she could instead be using a well documented, well tested, well known library. If he/she doesn't already know std::string, he/she could learn it & know that the knowledge will still be relevant if he/she changed companies (unlike effort spent to learn alex::string). When there's a bug they can be 99% sure its not a bug in the string class (although there seems to be no shortage of programmers that blame the compiler). They could post questions on programming forums about how to use std::string but not alex::string.
    That isn't so much a problem. Actually I added all standard member functions to my own string class just to meet that requirement. You should also see that the source code of existing STL implementations is without any comments and ugly to hell. So, debugging my own string class is much less frustrating than debugging into the basic_string. Did you ever debug into the 'traits' and didn't get lost somewhere? Same applies to documentation of basic_string which I wouldn't name 'well-documented'. IMO is really bad readable mostly due to the fact that they made it a template class which adds a complexity to the implementation and documentation that is unnecessary for everyone who knows which char type he was using.

    Also I don't share the idea that private implementations of a library can't have the same quality than a standard library. Actually I experienced more bugs and shortcomings of the various implementations of STL as it was with my own libraries which didn't change for years and are well-proved in many projects. For example all my containers were thread-safe and have no problems to be passed via dll boundaries. Last is, there was no alternative in the years before C++ standard ;-)


    Regards, Alex

    P.S.
    This wasn't a pleading for self-made libraries or for not using STL. On the contrary, I am a consequent user of those standards wherever it is possible. But I wasn't afraid of making or using my own libraries if it was required by the project or by the customer. And the basic_string class actually is a poor string class.

  11. #26
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: A question regarding *s++

    Quote Originally Posted by itsmeandnobodyelse View Post
    You should also see that the source code of existing STL implementations is without any comments and ugly to hell.
    Yes, STL implementations are typically geared towards getting the most out of the compiler they're written for. They are not intended to be readable directly.

    So, debugging my own string class is much less frustrating than debugging into the basic_string. Did you ever debug into the 'traits' and didn't get lost somewhere?
    No, there's no need to debug into basic_string because it doesn't have any significant bugs at this point. If the debugger tries to step into it, you just "Step out" and then "step in" again to make another try at getting where you intended to go.

    Any bug which seems to be in basic_string is simply the programmer's misuse or corruption of the object.

    Same applies to documentation of basic_string which I wouldn't name 'well-documented'.
    Eh, it's just fine for everything I need....
    http://www.cplusplus.com/reference/string/

    IMO is really bad readable mostly due to the fact that they made it a template class which adds a complexity to the implementation and documentation that is unnecessary for everyone who knows which char type he was using.
    Since basic_string is rarely instantiated with anything other than char or wchar_t, an argument could be made that it didn't have to be a template class. But I still think the template approach is superior to the CString solution, which is to have the observable class internals change depending on a preprocessor flag. That's just a bit nuts IMO.

  12. #27
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: A question regarding *s++

    I'm all for std::string, for the above reasons (Standard+already debugged).

    IMO, there is nothing wrong with templates. Once you get used to it, it really doesn't make any difference.

    Besides, a template form is needed for wstring...

    I DO think that std::string is a bit lacking in the interface/usability department.

    Sure, you can always get your work done by combining algorithms, search_first_of and erase/remove, but is it so much to ask for a "trim"?
    Is your question related to IO?
    Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

  13. #28
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: A question regarding *s++

    Ah, but the great thing about the design of the STL----including, for the most part, std::string----is that it's easily extensible.

    That's why we have options like the Boost String Algorithms library. Which does, by the way, include trim().

  14. #29
    Join Date
    Oct 2009
    Posts
    577

    Smile Re: A question regarding *s++

    Quote Originally Posted by Lindley View Post
    Ah, but the great thing about the design of the STL----including, for the most part, std::string----is that it's easily extensible.

    That's why we have options like the Boost String Algorithms library. Which does, by the way, include trim().
    Really? You can't safely derive from it, can you? You can't add new member functions therefore, right?

    Enhancements via function templates hardly can be used for praising a class design. On the contrary, they are global functions and I share the opinion that global functions mostly is poor OOP and the need for those functions show the heavy shortcomings of this class.

    Even my very first string class in the early 90's had better functionality and the missing 'trim' was only one of many evidences that they had many problems to integrate string semantics like 'whitespace', 'words', 'sentences', and more to their string class which IMO is not much more then a container for char types - where even a vector<char> has some advantages.

    Or take the case where you need to convert from wstring to string or vice versa or let alone character encoding like UTF-8 to ANSI and back. It is not alone that the basic_string doesn't give any concepts for this, it adds additional complexity to those conversions whenever different char types are involved.

    Regards, Alex

  15. #30
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: A question regarding *s++

    Quote Originally Posted by itsmeandnobodyelse View Post
    Really? You can't safely derive from it, can you? You can't add new member functions therefore, right?

    Enhancements via function templates hardly can be used for praising a class design. On the contrary, they are global functions and I share the opinion that global functions mostly is poor OOP and the need for those functions show the heavy shortcomings of this class.

    Even my very first string class in the early 90's had better functionality and the missing 'trim' was only one of many evidences that they had many problems to integrate string semantics like 'whitespace', 'words', 'sentences', and more to their string class which IMO is not much more then a container for char types - where even a vector<char> has some advantages.

    Or take the case where you need to convert from wstring to string or vice versa or let alone character encoding like UTF-8 to ANSI and back. It is not alone that the basic_string doesn't give any concepts for this, it adds additional complexity to those conversions whenever different char types are involved.

    Regards, Alex
    Well actually, some would say that in good OOP design, all these functions should NOT be member functions. The less member functions you have, the better.

    I mean, boost was able to expand on string (or string-like containers) an entire string library algorithm. If that's not Enhancement, I don't know what is.

    I'll grant you that basic_string is not great for holding (variable-sized) UTF, but it can hold char or wchar just fine, as well as any fixed size characters. You can convert one string type to another quite easily using iterator construction, provided you can construct the basic char type from the other type.

    No, what I think is that there should have been a <string_algorithm> class, just like boost's, but right in the STL.

    I know the STL philosophy is to not provide a tool if the combination of existing tools can do it for you (and they can), but I think there should have been an exception for strings, inside a library that operates specifically on strings.

    My choice of words "std::string is a bit lacking in the interface/usability department" may have been less than ideal, and I will correct myself to: "the STL offers little practical facilities for string manipulations, forcing the user into more direct (and bulky) string iterator+algorithm+functor manipulation". And I think it's a pity.
    Is your question related to IO?
    Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

Page 2 of 3 FirstFirst 123 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured