C++0x - a few doubts

This is a discussion on C++0x - a few doubts within the C++ Programming forums, part of the General Programming Boards category; Originally Posted by anonytmouse Is concept checking a worthwhile feature? I would have thought that programmers implementing an STL concept ...

  1. #16
    semi-colon generator ChaosEngine's Avatar
    Join Date
    Sep 2005
    Location
    Chch, NZ
    Posts
    597
    Quote Originally Posted by anonytmouse
    Is concept checking a worthwhile feature? I would have thought that programmers implementing an STL concept (how often is this done anyway?) would be fairly experienced and not require hand holding by the compiler.
    concept checking isn't really for the programmers writing the STL, it's for the users.

    for example, ever done this?
    Code:
    #include <vector>
    
    class MyClass
    {
    public:
    	MyClass(int x)
    		:m_x(x)
    	{}
    
    private:
    	const int& m_x;
    };
    
    int main()
    {
    	std::vector<MyClass> x;
    
    	x.push_back(MyClass(2));
    }
    the problem with this code is that MyClass has no available operator=, but the error output (VC7.1) produced is
    Code:
    c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\xutility(1136) : error C2582: 'operator =' function is unavailable in 'MyClass'
            c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\vector(862) : see reference to function template instantiation 'void std::fill<std::vector<_Ty>::_Tptr,_Ty>(_FwdIt,_FwdIt,const _Ty &)' being compiled
            with
            [
                _Ty=MyClass,
                _FwdIt=std::vector<MyClass>::_Tptr
            ]
            c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\vector(809) : while compiling class-template member function 'void std::vector<_Ty>::_Insert_n(std::vector<_Ty>::iterator,std::vector<_Ty>::size_type,const _Ty &)'
            with
            [
                _Ty=MyClass
            ]
            f:\tests\dlltest\testDll\testDll.cpp(19) : see reference to class template instantiation 'std::vector<_Ty>' being compiled
            with
            [
                _Ty=MyClass
            ]
    and clicking on it brings you to this function:
    Code:
    		// TEMPLATE FUNCTION fill
    template<class _FwdIt,
    	class _Ty> inline
    	void fill(_FwdIt _First, _FwdIt _Last, const _Ty& _Val)
    	{	// copy _Val through [_First, _Last)
    	for (; _First != _Last; ++_First)
    		*_First = _Val;
    	}
    the average C++ beginner sees this, screams and thinks "OMG my STL has been hax0red!!"

    A concept checked stl would produce something more along the lines of
    MyClass does not implement the Assignable concept
    and point you at the MyClass definition
    "I saw a sign that said 'Drink Canada Dry', so I started"
    -- Brendan Behan

    Free Compiler: Visual C++ 2005 Express
    If you program in C++, you need Boost. You should also know how to use the Standard Library (STL). Want to make games? After reading this, I don't like WxWidgets anymore. Want to add some scripting to your App?

  2. #17
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Portugal
    Posts
    7,578
    There does seem to be a broader use for Concepts. Implementators will benefit the most actually.

    For the user side, as you said, the error messages will be more concise and direct, hardly requiring code lookup to understand what is going on with their use of the STL. It will also shorten considerably the syntax in the usage of algorithms (and I believe some of the STL object data members).

    But the greatest benefit comes exactly to STL implementators. Exactly because Concepts will introduce improved type safety into the library. I think I read somewhere (I need to collect the sources, I know) that the greatest benefit comes from the fact that most of the informal rules that have been described so far in text, will now be able to be directly translated into C++ code. This is heaven to any STL implementator since they can easily ascertain their implementation against the Standard by simply... compiling it!

    One of the examples is the famous vector<bool>::iterator. The C++ standard erroneously states this to be a random iterator. But a concept check compiler will never allow this implementation. It will throw a compile time error. It knows that iterator doesn't meet the requirements of a Forward Iterator Concept. Of course, indirectly this will benefit the user too. The third advantage for the user would then be, more standard STL implementations across.

    After CornedBee reply it all suddenly clicked into place. The explanation was there black on white but I wasn't seeing past the idea these would be nothing more than real live abstract classes. I was strongly biased by it and some of the text was not making sense at all for me.
    The programmer’s wife tells him: “Run to the store and pick up a loaf of bread. If they have eggs, get a dozen.”
    The programmer comes home with 12 loaves of bread.


    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  3. #18
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Thanks, ChaosEngine, I hadn't considered the possibility of new Concepts which can apply to user types rather than only containers as they do currently.

    Mario F, thanks for pointing out the benefits to STL implementors. My query was whether this was worth the effort. But if Concepts can also be used by users, I guess the argument can be made.

  4. #19
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Just backing up a few posts:
    What will distinguish const_iterator from iterator? Surely not the compiler! Will it?

    Nothing does. Except this: right now, hardly anybody uses const_iterator if the source object isn't const, because it's too much to write. If the object IS const, then the compiler will correctly deduct const_iterator for auto. The non-const version of begin() won't be considered, because the object is const.
    Also, there's a proposal to add cbegin() and cend() etc. to all containers that are not overloaded on constness. I'm not sure if that proposal will go through.
    So then what happens when you use auto for a non-const container? Would non-const iterator be assumed? It seems like there would be ambiguities in other cases too, like auto-type parameters or return types (or.. wait, that would pretty much describe templated functions I guess).
    Last edited by Hunter2; 09-21-2006 at 12:53 PM.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  5. #20
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    Quote Originally Posted by Hunter2
    So then what happens when you use auto for a non-const container? Would non-const iterator be assumed?
    Yes.

    It seems like there would be ambiguities in other cases too, like auto-type parameters or return types (or.. wait, that would pretty much describe templated functions I guess).
    Not sure what you mean.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  6. #21
    Registered User
    Join Date
    Mar 2006
    Posts
    725
    I kinda like the new Concepts thing. Means I may not be seeing any more of those long long typename ridden error messages again. It's like a typedef for templates

    It only seems to make sense, though, that something which has always informally been omnipresent in the STL should make its way into the formal grammar of C++.


    It seems like there would be ambiguities in other cases too, like auto-type parameters or return types (or.. wait, that would pretty much describe templated functions I guess).
    Mario, C++ will always be strictly typed. The auto keyword, as you said earlier, is just syntactic sugar. The compiler will always know, regardless of context, what and how a function or expression returns a value -- otherwise it causes a compile error. So overloading auto this way shouldn't introduce any ambiguities AFAIK.

    Templates are also syntactic sugar, in fact. One could implement the same thing using some sort of macro based replacement system (there's an example in the wxWidgets code), but which would be more time consuming, less expressive and more error-prone. Concepts and auto may solve the same problem in other paradigm scopes.
    Last edited by jafet; 09-21-2006 at 01:23 PM.
    Code:
    #include <stdio.h>
    
    void J(char*a){int f,i=0,c='1';for(;a[i]!='0';++i)if(i==81){
    puts(a);return;}for(;c<='9';++c){for(f=0;f<9;++f)if(a[i-i%27+i%9
    /3*3+f/3*9+f%3]==c||a[i%9+f*9]==c||a[i-i%9+f]==c)goto e;a[i]=c;J(a);a[i]
    ='0';e:;}}int main(int c,char**v){int t=0;if(c>1){for(;v[1][
    t];++t);if(t==81){J(v[1]);return 0;}}puts("sudoku [0-9]{81}");return 1;}

  7. #22
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Portugal
    Posts
    7,578
    True. My only concern with the auto keyword is now the ease at which it can be abused. However, this is not the concern of the committee. It never was, and I bet many C/C++ programmers have thanked both committees for it never having been. The languages would have not been the same. On another hand, I think I can expect amibiguity situations caused from the use of the auto keyword with user-defined types to be dealt with by the compiler with error messages.

    Many other additions to the languages are expected. Regular expression and hash tables support, among my favorites. But also uniformity between std::string and C-style strings usage and, of course, smart pointers.

    I would also like to see virtual destructors for the STL containers to be moved up from wishlist.

    Anyways, the point being, that auto is just one of many additions and I now can see it is not the least a dangerous thing.
    The programmer’s wife tells him: “Run to the store and pick up a loaf of bread. If they have eggs, get a dozen.”
    The programmer comes home with 12 loaves of bread.


    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  8. #23
    Registered User
    Join Date
    Mar 2006
    Posts
    725
    My only concern with the auto keyword is now the ease at which it can be abused.
    If it can be abused, that means it is a powerful feature and should be used with care, that's all. The only noticable effect would probably be a larger influx of ignorant newbies to this board posting mindless questions about this new keyword.

    To be honest, I'd give much more for a consistent, quality stdlib than for language revolutions. Boost looks good, but it's rather big (Dev-C++ distro ~8 meg compressed binaries); I'm betting they'll have to decide which parts are important enough to leave in. If it is really added into the standard, Regex, Filesystem and other nice stuff should make the cut; then we can all code happily ever after.
    Code:
    #include <stdio.h>
    
    void J(char*a){int f,i=0,c='1';for(;a[i]!='0';++i)if(i==81){
    puts(a);return;}for(;c<='9';++c){for(f=0;f<9;++f)if(a[i-i%27+i%9
    /3*3+f/3*9+f%3]==c||a[i%9+f*9]==c||a[i-i%9+f]==c)goto e;a[i]=c;J(a);a[i]
    ='0';e:;}}int main(int c,char**v){int t=0;if(c>1){for(;v[1][
    t];++t);if(t==81){J(v[1]);return 0;}}puts("sudoku [0-9]{81}");return 1;}

  9. #24
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    Quote Originally Posted by Mario F.
    My only concern with the auto keyword is now the ease at which it can be abused.
    For obfuscation, you mean? People not bothering to type out any type anymore because they can use auto? Yes, that's probably a concern, especially for boards such as this.
    What I'm more afraid of is newbies not understanding why the type of an auto variable cannot change after initialization.

    On another hand, I think I can expect amibiguity situations caused from the use of the auto keyword with user-defined types to be dealt with by the compiler with error messages.
    I cannot imagine a situation where there would be ambiguity for the type deduction on the language level. On the understanding level, perhaps.

    I would also like to see virtual destructors for the STL containers to be moved up from wishlist.
    What for? Please no! I want my STL containers free of a vtable.


    Boost looks good, but it's rather big (Dev-C++ distro ~8 meg compressed binaries); I'm betting they'll have to decide which parts are important enough to leave in. If it is really added into the standard, Regex, Filesystem and other nice stuff should make the cut; then we can all code happily ever after.
    That's exactly what they're doing. Regex and filesystem are going in. The new iterators might go in, I'm not sure. (I want them to.) Smart pointers are in. Some other things, too.
    Other libraries, such as graph, Spirit, all that stuff, is not.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  10. #25
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Portugal
    Posts
    7,578
    > What for? Please no! I want my STL containers free of a vtable.

    I'm afraid I don't know what a vtable is. But I hope you follow on that thought

    Remember that this item on the wishlist is not a replacement of the current objects. From what I understand, it is instead new objects that mimic the standard ones but probably with names like virtual_vector or something like that. But I would like that. It strikes me as important the ability to derive from these containers.
    The programmer’s wife tells him: “Run to the store and pick up a loaf of bread. If they have eggs, get a dozen.”
    The programmer comes home with 12 loaves of bread.


    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  11. #26
    Registered User
    Join Date
    Jan 2005
    Posts
    7,344
    >> It strikes me as important the ability to derive from these containers.
    Why?

  12. #27
    Registered User
    Join Date
    Mar 2006
    Posts
    725
    EDIT: need to post quicker. Guys this post replies to Mario not Daved.

    Well, virtual classes use implicit pointers to do polymorphism. I think CornedBee is referring to the virtual method pointers for each class instance. They do add a significant amount of overhead for some types. Imagine trying to encapsulate POD in a virtual class and use it for video processing.

    Maybe you could define a new Concept called "Abstract", which would typically be implemented as a virtual class, and try to integrate it with the rest of the STL... oh, I don't know. Some of this 0x stuff is still speculation, anyway. I prefer just to wait and C on these things.
    Code:
    #include <stdio.h>
    
    void J(char*a){int f,i=0,c='1';for(;a[i]!='0';++i)if(i==81){
    puts(a);return;}for(;c<='9';++c){for(f=0;f<9;++f)if(a[i-i%27+i%9
    /3*3+f/3*9+f%3]==c||a[i%9+f*9]==c||a[i-i%9+f]==c)goto e;a[i]=c;J(a);a[i]
    ='0';e:;}}int main(int c,char**v){int t=0;if(c>1){for(;v[1][
    t];++t);if(t==81){J(v[1]);return 0;}}puts("sudoku [0-9]{81}");return 1;}

  13. #28
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Portugal
    Posts
    7,578
    How many classes are there that are built around a container only to provide the container with specific usage? Now... how many classes there are that then derive from this base class? I don't know any numbers, of course. But I feel this is not outrageous.

    To be able to create hierarchies with a container as a base and to be able to redefine the container functionality, seems a natural step in a programming language that we want OO capable. Especially taking into consideration the importance the STL container objects have. Maybe not a strictly necessity, but I'm not arguing about the STL being made OO. Simply think that a new library or appending OO functionality to the STL will ease many situations.
    The programmer’s wife tells him: “Run to the store and pick up a loaf of bread. If they have eggs, get a dozen.”
    The programmer comes home with 12 loaves of bread.


    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  14. #29
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    The vtable is the most common implementation strategy for virtual functions. You could visualize the implementation like this:
    Code:
    class Base
    {
      virtual ~Base();
      virtual void a() = 0;
      virtual void b();
    
      void nonvirt();
    
    // Compiler-generated:
      void **vptr;
      static void *vtable[3];
    };
    
    // Compiler-generated:
    void * Base::vtable[3] = {
      &Base::~Base, // Destructor
      0, // a()
      &Base::b // b()
    }; // No entry for nonvirt() - it's not virtual.
    Base::Base() : vptr(Base::vtable) {}
    
    class XXX : public Base
    {
      void a();
      void b();
    // Compiler-generated
      static void *vtable[3];
    };
    
    // Compiler-generated:
    void *XXX::vtable[3] = {
      &XXX::~XXX, // Destructor
      &XXX::a, // a()
      &XXX::b // b()
    };
    
    XXX::XXX()
    {
      // Override assignment
      vptr = XXX::vtable;
    }
    
    class YYY : public Base
    {
      void a();
      // No b()
      virtual void c();
    // Compiler-generated
      static void *vtable[4];
    };
    
    // Compiler-generated
    void *YYY::vtable[4] = {
      &YYY::~YYY // Destructor
      &YYY::a // a()
      &Base::b // b()
      &YYY::c // c()
    };
    
    YYY::YYY()
    {
      // Override assignment
      vptr = YYY::vtable;
    }
    A call to a virtual function undergoes a translation:
    Code:
    Base *ptr = getABase();
    
    ptr->b();
    // becomes:
    void (*t)(Base*) = reinterpret_cast<void (*)(Base*)>(ptr->vptr[index_of(b)]); // index_of(b) == 2
    t(ptr);
    It should be mentioned that the cast is highly invalid C++, of course. You can no more cast between data pointers (such as void*) and function pointers than it is valid to cast a member pointer to any other function pointer. But that's effectively what happens at the assembly level.

    Of course, with multiple bases and virtual inheritance, the whole thing becomes far, far more complicated. But for simple hierarchies, this is the general dispatch method.

    A class only has a vtable and a vptr member if it has at least one virtual function. Thus, the first virtual function a class has adds sizeof(pointer) to every single instance. That's 8 bytes on my AMD64 box that I really don't want to have in every container.

    I see very little need to derive from the standard containers. And remember this: you can always derive from every class, even if it doesn't have a virtual destructor. The only thing is, you cannot allow that class to be destructed with a static type of the base class, i.e. having delete called on a pointer to the base. That leads to undefined behaviour, since due to the destructor not being virtual, there is no guarantee that the most derived destructor is invoked by this operation.
    In other words, you can always safely derive privately from any class, unless that class contains a "delete this" somewhere.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  15. #30
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Portugal
    Posts
    7,578
    > They do add a significant amount of overhead for some types.

    I would say them all probably. But again, the proposal is not to replace the current STL.... a sec while I refer back to the wishlist to give you the exact quote... "Versions of the standard containers with virtual destructors".

    It is up to the user to identify when he needs to use these versions and if the obvious speed tradeoff is of any concern. More often than not it probably won't be.
    The programmer’s wife tells him: “Run to the store and pick up a loaf of bread. If they have eggs, get a dozen.”
    The programmer comes home with 12 loaves of bread.


    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

Page 2 of 3 FirstFirst 123 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Doubts regarding random numbers generation
    By girish1026 in forum C Programming
    Replies: 9
    Last Post: 12-31-2008, 10:47 PM
  2. More questions (relating to global doubts)
    By Jorl17 in forum C++ Programming
    Replies: 29
    Last Post: 12-03-2008, 11:40 AM
  3. Some doubts on DLLs
    By BrownB in forum Windows Programming
    Replies: 1
    Last Post: 05-30-2007, 03:25 AM
  4. Two doubts about C for my project
    By j0nnyX in forum C Programming
    Replies: 4
    Last Post: 10-11-2004, 03:31 PM
  5. doubts on scanf
    By aqua in forum C Programming
    Replies: 1
    Last Post: 10-28-2002, 04:20 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21