CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 11 of 19 FirstFirst ... 891011121314 ... LastLast
Results 151 to 165 of 280
  1. #151
    Join Date
    Apr 1999
    Posts
    27,449
    Originally posted by Yves M
    Well, STL is indeed difficult to read if you are not used to templates. If you don't know much of STL it's not making things better either. This is one of the reasons, I guess, students are not really taught to use STL at college. Then again there can be a host of other reasons.
    Some C++ textbooks are introducing STL right away. For example "Acclerated C++" introduces the "vector" and "string" before talking about arrays and char *

    It's all in how you introduce the topic. If a student has never seen a template, then a template won't scare them away and using vector<>, list<>, string, etc. is "natural" to them.

    On the other hand, if the same student has been taught procedural, C-like coding, and then introduced to a templates, then things get trickier and more difficult for them to understand.

    Here is what Stroustrup has to say in teaching C++.
    http://www.research.att.com/~bs/new_learning.pdf

    And here is his paper on why C++ is not just an OO language:
    http://www.research.att.com/~bs/oopsla.pdf

    Regards,

    Paul McKenzie

  2. #152
    Join Date
    Nov 2003
    Posts
    74

    My 2 cents

    Pardon me if some of this has been covered but I am still reading the post. I have been programing for 5 years now and I have found that there are cases where both are nice but I like the stl much more than the MFC objects.

    quote:
    --------------------------------------------------------------------------------
    Oh and by the way, in STL I can code, say a vector which is full of memory leaks by doing this :



    code:
    --------------------------------------------------------------------------------
    stl::vector<MyClass>
    --------------------------------------------------------------------------------


    If 'MyClass' has a memory leak in it, then I can't tell where the memory leak occurs, although it's perfectly valid in stl terms.

    See what I mean yet ? STL is open to memory leaks !

    In programming terms the above is not only possible, but very probable that you would do that.
    --------------------------------------------------------------------------------

    This is just bad programming by you. You should test out your class before you go using it anywhere.

    quote:
    --------------------------------------------------------------------------------
    Originally posted by darwen
    Code should never, ever be released in library form. It should always take the form of COM objects or DispInterface objects.
    --------------------------------------------------------------------------------

    Answer me this, why would you use MFC in a COM object anyways? I use only STL and ATL code in COM Objects because it reduces the number of dependencies. Also if you are developing a Service or win32 application (non gui) why would you bloat it in size by adding MFC references when the STL would suit the same purpose. Also by using the STL you can then using the same code in a GUI version of the app without having to re-write it.

    In the case of derivation, you are just going to pass around an instance of it, so why not write a class where the container behind it is non-dependant and then just have functions to access what you need from the class including the functions to sort. The only time you need to write a function to sort for STL is when the object in the container is a nonstandard object (your on class) and then you just create a function to do the compare and pass that into the sort call.

    By using STL anyone who is familiar with C++ (be it Borland under windows, or Linux/Unix programer, or MS Visual Studio Programmer) can look at the code and know what it is doing. Also the STL is developed and tested by some of the best developers in the community and conforms to the ANSI standard. As long as you are using the released build and not the beta builds you are usually sure you are getting a good version of the STL. MFC is hardly updated and some of its code dates back to Windows 3.1 days and hasn't been updated. You only see an updated to the MFC when a new compiler/IDE comes out from MS. If you need support you can get alot of support from the community for both, but if you need an update or a bug-fix, it is released and tested faster with STL.

    Also STL is nice cause it is type independant. You only have to write a function for compare or sort which compares what you want and it then handles the rest. This function then works no matter what type of container you use (list, vector, map, etc.) Where as you would have to change and copy the same code if you did it for MFC.
    Last edited by Adam Gritt; November 24th, 2003 at 02:11 PM.

  3. #153
    Join Date
    Sep 2002
    Location
    14° 39'19.65"N / 121° 1'44.34"E
    Posts
    9,815
    As this is the VC++ forum, a thing to mention when talking about templates and the STL is how badly MS supports them in VC++. When templates first became part of the standard, MS took their time to come up with a VC++ version which supported them at all. And when it came to including the STL, the first implementations they delivered with VC++ were buggy, and the online MSDN documentation regarding the STL is unusable, near to nonexistant. They seemed to express the defiant attitude "OK, so the standard demands that we include the STL. Here it is. Let's see if people will really use it, or continue to use the MFC container, file and string classes as they are supposed to."
    Another problem is they way the compiler handles errors in code using templates: Mostly unaware of the template level, on the level of the expanded code. So in most situations, when you have a simple syntax error in code involving the use of templates, instead of getting an error message referring to the statement you wrote, the compiler throws several lines of expanded template code at you, and your first reaction is something like "What the f...! I never wrote that code!" Likewise, whith an error in code calling a member of an STL class, you're likely to end up with the compiler flagging the error in the STL code, not in your code.

    Those things, although they have little to do with templates and the STL themselves but with the way MS supports them, are however pragmatical points to consider, and I'm sure they contributed to making many developers reluctant about using STL (or templates in general) in the VC++ environment.

  4. #154
    Join Date
    Apr 1999
    Posts
    27,449

    Re: My 2 cents

    Originally posted by Adam Gritt
    This is just bad programming by you. You should test out your class before you go using it anywhere.
    This is true. If the class can't be used in an STL container (causes "memory leaks"), it certainly can't be used where copying or assignment will take place, STL or no STL. Just passing or returning the object by value would make it unusable and unstable. I tried to make this point much earlier in the thread, but it wasn't picked up on. Once again:
    Code:
    DarwensClass foo()
    {
        DarwensClass dc;
        return dc;
    }
    
    int main()
    {
       DarwensClass a;
       DarwensClass b;
       a = b;
       DarwensClass c = a;
       DarwensClass d = foo();
    }
    If DarwensClass causes "memory leaks" and crashes when used in a vector, it will cause memory leaks and would more than likely crash the simple program above.
    By using STL anyone who is familiar with C++ (be it Borland under windows, or Linux/Unix programer, or MS Visual Studio Programmer) can look at the code and know what it is doing.
    Which is the point being made in the previous posts by Yves. We understood what the code posted does, and would understand practically any of the samples given in MSDN. I don't know why darwen believes that others don't understand STL, just because he has a hard time with the syntax not being "clean".
    Also STL is nice cause it is type independant. You only have to write a function for compare or sort which compares what you want and it then handles the rest. This function then works no matter what type of container you use (list, vector, map, etc.) Where as you would have to change and copy the same code if you did it for MFC.
    For the MFC array containers, you can use std::sort on them and not even have to write your own sort. So even if you did use MFC, the algorithm functions can be used on the MFC array containers. The std::sort is a perfect example of how an STL algorithm "adapts" to any kind of container that has iterators that meet the requirements. The CIntArray, CByteArray, CStringArray, and CArray<> template classes can be used in most STL algorithm functions. I even wrote an entry in FAQ on sorting MFC array containers using std::sort. If anyone hates STL so much as to not even use the algorithm functions, then there is something amiss somewhere.

    Regards,

    Paul McKenzie

  5. #155
    Join Date
    Apr 1999
    Posts
    27,449
    Originally posted by gstercken
    As this is the VC++ forum, a thing to mention when talking about templates and the STL is how badly MS supports them in VC++.
    MS is making strides with their current VC++ compiler to adhere to the standard (thanks in part to Herb Sutter's contributions). A lot of the template code that couldn't compile with VC 5.0 and VC 6.0 are now compilable with VC 7.0x.

    Also, MSDN is not a good reference, even for the C-library functions. I wouldn't count on using MSDN to teach C++ or how to use C++ correctly -- that is reserved for books and the classroom. If you just need a refresher, then MSDN is usable, but IMO you can't use it as a teaching tool. Too many new programmers make this mistake of using MSDN as the "be-all, end-all" in C++ coding, and thus believe that STL is something not important or hard to understand.

    Regards,

    Paul McKenzie

  6. #156
    Join Date
    Nov 2003
    Posts
    74
    Originally posted by gstercken
    Those things, although they have little to do with templates and the STL themselves but with the way MS supports them, are however pragmatical points to consider, and I'm sure they contributed to making many developers reluctant about using STL (or templates in general) in the VC++ environment.
    That is true. I even ran into the issue of purchasing the DinkumWare version over using the VC++( bastardized dinkumware) version. Once I did that I ran into far less problems. With the new .Net 2003 compiler, ANSI support and therefore Template support is much better (98% of standard) and anyone would be hard pressed to find a better compiler right now. As to the Microsoft help, they are probably of the decision "we didn't write it so why should we support the documentation of it". Although it has gotten better, I find much of the development sites out there for STL to provide the most in depth documentation.

  7. #157
    Join Date
    Jan 2002
    Location
    Scaro, UK
    Posts
    5,940
    Re: Adam Gritt.

    Ah but my point is : I've seen code with this sort of memory leak in it. You may say it's bad programming practice, and every class should be tested but : who has time to extrenuously test every class in an application ? I certainly don't.

    In fact I've had to fix code with memory leaks such as this in them and it's taken days not minutes to track them down.

    No, I didn't write them and yes we do consider the guy who wrote them an idiot which is why he's no longer with the company but in the real world you do have idiots which do things like this. At least the memory leak reporting in VC allows you to fix such things without much trouble.

    I must admit saying that things should only be released in COM form was stupid as MFC is a library. I must get my dunce hat on.

    In actual fact I've never had a problem with statically linking MFC to apps - these days size doesn't matter (certainly on desktops, palmtops may be another issue).

    But then again, aren't I right in saying that templated code is expanded internally by the compiler ? Maybe not, I dunno. But if it is then every call to every class in the STL will be expanded causing the exe size to grow exponentially. Then again, I'm not too sure about this point and I'm sure someone will say its not.
    But if I'm right then in very large applications it's much more sensible to use a library such as MFC which is statically linked because it's of a fixed size and doesn't add 50 lines of code for every class member call (or whatever - I'm generalising I know).

    Nope, still prefer MFC thanks.

    Darwen.

  8. #158
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626
    I feel I must add to this discussion.

    Darwen: If you hate STL, then don't use STL, it's your right to decide to do so. It's as much a choice whether or not to use STL as is the choice of programming language.
    Are you missing out if you don't use STL... yup, you sure are. And you're missing out for not using VB which is much easier for COM, you're missing out for not using Assembly which can be much faster, you're missing out for not using MSDOS which doesn't need a gui....


    I've been doing C++ programming for over a decade now. I've probably written a few million lines of C++ code by now.

    I've never really needed STL. In fact, In all that time, I've never even written a template class of my own (except for testing/learning purposes). I just never seemed to get a problem where a solution with templates was a better approach than a solution without. And it's generally a bad idea to use features 'just because it's there'.
    For MFC code (the large bulk of my Windows apps), the MFC container classes have always managed to do what I needed.

    If you're linking with MFC, then it's a good idea to use the MFC containers, because it's there anyway. You don't get any extra size overhead by using them. Using STL however WILL add some extra code.

    --
    Until some years ago, there was a problem with using templates, because compilers/linkers were fairly dumb. Instantiating entire template classes, even if you used only a small portion of it, leading to bulky exe's (I've seen compilers churn simple bits of C++ code (up to 10 lines or so) into 12Mb exe's).
    At least this has disappeared on a module per module basis. But last time I checked (with VC6), it still added plenty overhead if you use DLL's.
    If you have many interdependant DLLs, and use identical STL derived classes in them, you end up with instances of the same code over and over and over.
    With MFC, there is exactly one instance of the code in the MFC DLL. Regardless of in what DLL's use the container (they do need to link with the MFC DLL of course)
    This for me is a big issue. When (just out of curiosity) I changed the code for one project to use all STL containers instead of MFC containers, I ended up with an additional 25Mb of code in a total of 53 DLL's. Quite a severe penalty if you ask me.
    Of course... I may be missing out on a compiler feature, C++ language feature or just overlooking the obvious. Anyone care to enlighten me ? :-)

  9. #159
    Join Date
    Nov 2002
    Location
    Foggy California
    Posts
    1,245
    Originally posted by darwen
    Ah but my point is : I've seen code with this sort of memory leak in it. You may say it's bad programming practice, and every class should be tested but : who has time to extrenuously test every class in an application ? I certainly don't.
    All code should be tested. Extrenuously? Well, there is a point-of diminishing returns. However, checking a class for memory leaks should not be beyond that point.

    Originally posted by darwen
    But then again, aren't I right in saying that templated code is expanded internally by the compiler ? Maybe not, I dunno. But if it is then every call to every class in the STL will be expanded causing the exe size to grow exponentially. Then again, I'm not too sure about this point and I'm sure someone will say its not.
    But if I'm right then in very large applications it's much more sensible to use a library such as MFC which is statically linked because it's of a fixed size and doesn't add 50 lines of code for every class member call (or whatever - I'm generalising I know).
    First off, as you guessed, you are wrong about the "exponential" growth. Usually (the specifics are left to the vendor of the compiler), the compiler will expand the definition for a class or function once and compile it. Not all template code is inline. In this case the growth would be linear -- on par with just about any other code.

    Second, the complaints you mention would apply to all template classes and functions, not just to the STL. It seems that you don't like templates, not just the STL. Is this a fair assessment?

    Last, MFC adds a few hundred thousand if not million lines of code behind the scene and can add MB's to the size of memory an application takes in memory. Usually using template code (STL or not) will not add that much. However, OReuben is correct in that if you are already using MFC, then using the MFC containers will not add more overhead, whereas using templates (or the STL) will (though probably not as much as you think).

    Anyway, if you don't like templates, don't use them. Those that feel comfortable using them will.

    - Kevin
    Last edited by KevinHall; November 24th, 2003 at 05:27 PM.

  10. #160
    Join Date
    Jul 2002
    Posts
    107
    OReubens:
    Yes indeed, STL is inline so it's expanded by the compiler. There are various mods that will change that separate link instances based on class type which can minimize on the overhead.

    Not that I wanted to get into all this again but since my buddy over there has realized its not some much fun on the receiving end of the abuse, and I think this can be settled easily so here it is:

    STL Vector push_back will be my benchmark example:
    All code is from 'vector' header file in VC6. I do understand they cleaned it up in .NET which is nice.

    Code:
     
    void push_back(const _Ty& _X)
        {insert(end(), _X); }
    void insert(iterator _P, size_type _M, const _Ty& _X)
        {if (_End - _Last < _M)
            {size_type _N = size() + (_M < size() ? size() : _M);
            iterator _S = allocator.allocate(_N, (void *)0);
            iterator _Q = _Ucopy(_First, _P, _S);
            _Ufill(_Q, _M, _X);
            _Ucopy(_P, _Last, _Q + _M);
            _Destroy(_First, _Last);
            allocator.deallocate(_First, _End - _First);
           _End = _S + _N;
           _Last = _S + size() + _M;
           _First = _S; }
        else if (_Last - _P < _M)
            {_Ucopy(_P, _Last, _P + _M);
            _Ufill(_Last, _M - (_Last - _P), _X);
            fill(_P, _Last, _X);
            _Last += _M; }
        else if (0 < _M)
            {_Ucopy(_Last - _M, _Last, _Last);
            copy_backward(_P, _Last - _M, _Last);
            fill(_P, _P + _M, _X);
            _Last += _M; }}
    I think its been decided that one letter variable names is bad programming....and very bad design. All the other functions are inline as well and in that header file.

    Since this is inline, you can expand that mess and see that you're looking at around 20 odd lines of inline code per insertion. Generally more lines, more overhead...Never mind the overhead from the assignments.

    Here is my own 'vector' style class. Has all the fat cut out and is drop in compatible with vector.
    Its a template class for generic list type.
    tpListType is the generic list type.

    Code:
    //linknode is defined to have a tpListType data, and linkNode<tpListType> prev and next ptr. Simple dblLinked list config.
    bool push_back(const tpListType& Elem){
        if(!first){
            first = new linkNode<tpListType>;
            if(!first) return false;
            first->data = new tpListType(Elem);
            if(!first->data) return false;
            last = first;
            NumberOfElements++;
            return true;
        }
        else{
            linkNode<tpListType>* ptr = new linkNode<tpListType>;
            ptr->data = new tpListType(Elem);
            if(!ptr->data) return false;
            ptr->next = 0;
            ptr->prev = last;
            last->next = ptr;
            last = ptr;
            NumberOfElements++;
            return true;
        }
    }
    Easy to read, completely encapsulated, meaning, that no outside user can modify internal data, once in list, the internal data can only be modified by the class though calls. This protects the data from anybody using it. I consider this good design. When you build a car, you don't let a driver easily reach in and yank on the valves. Don't have to worry about list size being wrong since nobody should be messing with variables like NumberOfElements.
    I believe its understood that user safe objects are good design.

    And then there's CArray which just isn't worth the hassle of pasting....

    Benchmarks:
    Compiled in release, would do debug, but I'm still waiting for CArray to come back....

    std::vector<int>
    MyTemplateList<int>
    CArray<int, int>

    this loop on a Pentium 2Ghz machine for each list, 1 millions inserts
    for(int i = 0; i < 1000000; i++){
    // add 1 element
    }

    vector.push_back(i) = 1.2 seconds.
    MyTemplateList.push_back(i) = 0.6 seconds.
    CArray.Add(i) = 12 seconds.

    So as you can see, and feel free to try, user written is fastest (providing done right), STL is middle and CArray is so poor that last is too good for it....
    But to give CArray some credit, its far more defensible and easier to debug then STL.

    So you decide which you feel is "better"....Again I vote user written because you control the performance and you know you can be at least as fast as the library, have more functionality and be better designed, which is everything you could want in a program or library.

  11. #161
    Join Date
    Jun 2003
    Location
    Armenia, Yerevan
    Posts
    720
    Why are you comparing vector.push_back() with your list's push_back(), compare with std::list's push_back, it's obvious that inserting in vector is more expensive than in list.

  12. #162
    Join Date
    Nov 2002
    Location
    Foggy California
    Posts
    1,245
    Actually, I bet vector<>.push_back would be much, much quicker (than even list<>.push_back) if you reserved the memory beforehand:

    Code:
    std::vector<int> x;
    
    x.reserve(1000000);
    for(int i = 0; i < 1000000; i++){
        x.push_back(i);
    }

  13. #163
    Join Date
    Sep 2002
    Location
    14° 39'19.65"N / 121° 1'44.34"E
    Posts
    9,815
    Originally posted by oktronic
    vector.push_back(i) = 1.2 seconds.
    MyTemplateList.push_back(i) = 0.6 seconds.
    CArray.Add(i) = 12 seconds.

    So as you can see, and feel free to try, user written is fastest (providing done right), STL is middle and CArray is so poor that last is too good for it....
    But to give CArray some credit, its far more defensible and easier to debug then STL.
    Set aside the readability of the code: What you have implemented here is a linked list, not a vector. And while a vector's strong point is to access elements in constant time using an index, the cost for inserting and removing elements depends highly on the implementation (especially the strategy used to resize the array when needed), and that's why CArray is so slow here: With its default grow value, it is not optimized for insertion of a large number of elements at the end. You can easily change that if you call SetSize(1000000) and then re-run your benchmark.
    In contrast, the data structure you implemented (a linked list) is especially efficient at adding elenments at the end (the case you have used for the benchmark), but what about running a benchmark which tries to retrieve an element at an arbitrary index n times?
    Anyway, given that you cheated by comparing a linked list with a vector for appending elements at the end, I think that std::vector does a terribly good job in taking only twice the time as your linked list implementation...

  14. #164
    Join Date
    Apr 1999
    Posts
    27,449
    Originally posted by oktronic
    Here is my own 'vector' style class. Has all the fat cut out and is drop in compatible with vector.
    Just to add to others comments:

    a)Your version returns a bool -- vector::push_back() returns void.

    b) Current standards state that when "new" fails, a bad_alloc exception is thrown, not a NULL return value. It may work for VC 6.0 and maybe the current version of VC 7.0, but from all indications, MS will start to use the standard way to report a failure of operator new, so your code will have to be rewritten if you port it to a newer version of VC++ (or another compiler).

    c) Your code assumes that the allocator is operator new[], and not a possible custom allocator.

    d) Not seeing your constructor, operator =, or copy, it's hard to put up timing just for push_back. It all depends on what you want to do, and real programs don't just call push_back. Also, do you have a reserve() function for your class? If not, did you try this code:
    Code:
    std::vector<int> IntV;
    IntV.reserve(1000000);
    for(int i = 0; i < 1000000; i++)
    {
       push_back(i);
    }
    This should run somewhat faster than the time you posted (maybe still not as fast as your version, but it should be faster).

    Maybe some MFC expert on CArray can chime in on whether there is a "reserve"-like function for CArray. If there is, you need to re-time the tests, taking in consideration that these functions exist.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; November 24th, 2003 at 06:37 PM.

  15. #165
    Join Date
    Apr 1999
    Posts
    27,449
    Originally posted by KevinHall
    Actually, I bet vector<>.push_back would be much, much quicker (than even list<>.push_back) if you reserved the memory beforehand:

    Code:
    std::vector<int> x;
    
    x.reserve(1000000);
    for(int i = 0; i < 1000000; i++){
        x.push_back(i);
    }
    Hey, you beat me to it!

    Regards,

    Paul McKenzie

Page 11 of 19 FirstFirst ... 891011121314 ... 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