c9xeo> Great talk, it's always a joy to hear you talking!
Thanks!
c9xeo> I hope you'll have a little bit more time for your Advanced STL series once VS11 is out.
Me too. You can think of this as "Advanced STL, Part Infinity" for the time being. :->
c9xeo> Then, any particular reason that nearly every slide was titled with a TVTrope?
I came up with "Twenty Minutes Into The Future" and "The Reveal" first, and I liked them so much, I had to follow the pattern. :->
c9xeo> (Also, can we get access to these slides?)
The links are above: "Slides (view online)"
someone> What are cars, putters and stoods??!
I pronounce "char", "ptr", and "std" as "care" (it's the prefix of "character"), "putter", and "stood".
C64> So, when we have a C++ class X and we want to modify a copy of it inside a function/method, does it make sense (also in C++98/03) to always use signature like your #2?
Yes. It's sometimes better, and never worse. The advantage increases in C++11, but is present in C++98/03.
I was taking shortcuts - move semantics would have been involved if the sources were str + "stuff" - but the point still holds.
Compare:
flip(const string& s) { string ret(s); // #1, reverse and return ret
versus:
flip(string s) { // #2, reverse and return s
Given flip("meow"), #1 creates a temporary string, binds the const reference s to it, then (unnecessarily!) copies it into ret. #2 constructs s from "meow", as you mentioned, then flips and move-returns it.
So, #2 made sense even in C++98/03, and it plays nice with move semantics.
NotFredSafe> I'm a bit surprised STL did not comment on this since. Unless I'm mistaken, this issue is one of his pet peeves
I missed it.
thesaint> Nobody is talking about push_back...
What are you referring to, then?
vector always grows geometrically, not arithmetically. This is true for push_back(), emplace_back(), element insert(), range insert(), resize(), everything. The lone exception is reserve(), which is permitted to give you exactly as much memory as you ask for (and typically will), which can trigger quadratic complexity if you're not careful (I've hit this myself).
> I am confuse on how you can talk about the difference between list and vector in performances because of their layout and design and at the same time say that you shouldn't teach student about cache lines, and the low hardware stuff.
1. vector and list are massively different in terms of what you can do with them - vector has op[], list has push_front, etc. In contrast, caching effects don't affect what you can write - only how fast it is. (Hardware engineers go to great lengths to preserve the illusion that memory is flat and simple!)
2. vector and list affect asymptotic complexity (this was the point of Bjarne's once-invisible graph) - yay computer science! Caching effects do not.
3. The difference between vector and list is very simple to explain - it can be explained to beginning programmers with simple diagrams. Caching effects are not as simple.
4. The difference between vector and list is fundamental and architecture-independent. Caching effects are strongly architecture-dependent (and have changed over time).
5. It is easy to deal with the difference between vector and list - use vector as your default sequence container because it's so awesome. It is not trivial to write code that respects cache lines and so forth.
When I'm explaining vector to beginners, I usually say, "Look, it's contiguous. This is space-efficient, and processors love blasting through memory in a straight line", and leave it at that. That's all you need to know when you're starting out.
> 1. C++11 adds new cool features to the language, but would it mean that compile time of C++ code will increase notably, especially on medium-large code bases?
In general, it shouldn't - especially if you aren't using the new features.
Some things do increase compile time. For example, C++11's allocator_traits is mandated to check for the existence of various types and member functions, which is relatively expensive, and this affects code using the STL. (In this case, we were able to eliminate the penalty by providing a specialization for allocator_traits<allocator<T>> that already knows the right answers.)
On the other hand, real variadic templates will significantly reduce compile time and compiler memory usage - the simulated variadic templates we've been spamming out since VC9 SP1 are very stressful on the compiler.
devcodex> is there any chance that we can the current "infinity" for the faked variadic templates back to 10 from the current 5?
Simply define _VARIADIC_MAX to 10 project-wide.
The compiler issue (excessive memory consumption triggered by default template arguments) that originally motivated us to lower infinity's default from 10 to 5, as well as another issue (lambdas with excessively long mangled names, further multiplied by the STL) have been fixed by JonCaves, so I don't believe there's anything stopping me from raising the default back to 10 - except for compilation speed. Our testers have noticed that our libraries are taking longer to compile (it's not huge, but it's like 10%-20% in various example projects). Some of this is necessary because we're implementing more stuff mandated by C++11. I've already implemented a workaround for one thing (allocator_traits) required by C++11, but where we can take a shortcut that's much cheaper to compile and has indistinguishable results. We're not currently aware of other places where we can increase compilation speed - except for _VARIADIC_MAX. Defaulting to 5 results in greater compilation speed for everyone who doesn't need huge tuples/etc. and the people who do need them are "nicely" informed with compiler errors. (I should probably write a blog post about this - I've mentioned in several times in passing, but not in a whole dedicated post.) Defaulting to 10 would allow all code that compiled with VC9 SP1 and VC10 RTM/SP1 to continue to compile with VC11 - but at the cost of slower compilation speed for everyone who doesn't need infinity to be big.
I haven't heard a *whole* lot of grumbling about infinity=5 so my current plan is to leave it that way. If we get a lot of feedback, increasing the default is trivial, so there's plenty of time to change this later.
C64> I've not tried myself, but you may want to try to pass a VC9 (VS2008 SP1)'s shared_ptr across module boundaries with a module built with VC10 (VS2010)...If the layout and implementation of shared_ptr of these two different compilers differ, you have crash and burn.
The STL never has and never will guarantee binary compatibility between different major versions. We're enforcing this with linker errors when mixing object files/static libraries compiled with different major versions that are both VC10+, but for DLLs and/or VC9-and-earlier, you're on your own when it comes to following the rules.
STL11: Magic && Secrets
1 day ago(never mind)
STL11: Magic && Secrets
1 day agoc9xeo> Great talk, it's always a joy to hear you talking!
Thanks!
c9xeo> I hope you'll have a little bit more time for your Advanced STL series once VS11 is out.
Me too. You can think of this as "Advanced STL, Part Infinity" for the time being. :->
c9xeo> Then, any particular reason that nearly every slide was titled with a TVTrope?
I came up with "Twenty Minutes Into The Future" and "The Reveal" first, and I liked them so much, I had to follow the pattern. :->
c9xeo> (Also, can we get access to these slides?)
The links are above: "Slides (view online)"
someone> What are cars, putters and stoods??!
I pronounce "char", "ptr", and "std" as "care" (it's the prefix of "character"), "putter", and "stood".
C64> So, when we have a C++ class X and we want to modify a copy of it inside a function/method, does it make sense (also in C++98/03) to always use signature like your #2?
Yes. It's sometimes better, and never worse. The advantage increases in C++11, but is present in C++98/03.
STL11: Magic && Secrets
5 days agoI was taking shortcuts - move semantics would have been involved if the sources were str + "stuff" - but the point still holds.
Compare:
flip(const string& s) { string ret(s); // #1, reverse and return ret
versus:
flip(string s) { // #2, reverse and return s
Given flip("meow"), #1 creates a temporary string, binds the const reference s to it, then (unnecessarily!) copies it into ret. #2 constructs s from "meow", as you mentioned, then flips and move-returns it.
So, #2 made sense even in C++98/03, and it plays nice with move semantics.
Interactive Panel: The Importance of Being Native
5 days agoNotFredSafe> I'm a bit surprised STL did not comment on this since. Unless I'm mistaken, this issue is one of his pet peeves
I missed it.
thesaint> Nobody is talking about push_back...
What are you referring to, then?
vector always grows geometrically, not arithmetically. This is true for push_back(), emplace_back(), element insert(), range insert(), resize(), everything. The lone exception is reserve(), which is permitted to give you exactly as much memory as you ask for (and typically will), which can trigger quadratic complexity if you're not careful (I've hit this myself).
Interactive Panel: The Importance of Being Native
6 days agothesaint> The key difference between "list" and "vector" is that, unless I am forgetting some "list" members here, "list" is just plain useless.
Not quite - it has very nice invalidation guarantees.
Day 1 Keynote - Bjarne Stroustrup: C++11 Style
6 days agoThe range-based for-loop is significantly less verbose than std::for_each() (my least favorite STL algorithm).
But using more specific STL algorithms is always a good idea.
Interactive Panel: The Importance of Being Native
Feb 03, 2012 at 5:56 AM> I am confuse on how you can talk about the difference between list and vector in performances because of their layout and design and at the same time say that you shouldn't teach student about cache lines, and the low hardware stuff.
1. vector and list are massively different in terms of what you can do with them - vector has op[], list has push_front, etc. In contrast, caching effects don't affect what you can write - only how fast it is. (Hardware engineers go to great lengths to preserve the illusion that memory is flat and simple!)
2. vector and list affect asymptotic complexity (this was the point of Bjarne's once-invisible graph) - yay computer science! Caching effects do not.
3. The difference between vector and list is very simple to explain - it can be explained to beginning programmers with simple diagrams. Caching effects are not as simple.
4. The difference between vector and list is fundamental and architecture-independent. Caching effects are strongly architecture-dependent (and have changed over time).
5. It is easy to deal with the difference between vector and list - use vector as your default sequence container because it's so awesome. It is not trivial to write code that respects cache lines and so forth.
When I'm explaining vector to beginners, I usually say, "Look, it's contiguous. This is space-efficient, and processors love blasting through memory in a straight line", and leave it at that. That's all you need to know when you're starting out.
GoingNative 2012: All Sessions are now available On-Demand!
Jan 23, 2012 at 2:51 PM> 1. C++11 adds new cool features to the language, but would it mean that compile time of C++ code will increase notably, especially on medium-large code bases?
In general, it shouldn't - especially if you aren't using the new features.
Some things do increase compile time. For example, C++11's allocator_traits is mandated to check for the existence of various types and member functions, which is relatively expensive, and this affects code using the STL. (In this case, we were able to eliminate the penalty by providing a specialization for allocator_traits<allocator<T>> that already knows the right answers.)
On the other hand, real variadic templates will significantly reduce compile time and compiler memory usage - the simulated variadic templates we've been spamming out since VC9 SP1 are very stressful on the compiler.
GoingNative 4: Jim Springfield on ATL, GoingNative Conference - Register Today!
Nov 27, 2011 at 2:33 PMdevcodex> is there any chance that we can the current "infinity" for the faked variadic templates back to 10 from the current 5?
Simply define _VARIADIC_MAX to 10 project-wide.
The compiler issue (excessive memory consumption triggered by default template arguments) that originally motivated us to lower infinity's default from 10 to 5, as well as another issue (lambdas with excessively long mangled names, further multiplied by the STL) have been fixed by JonCaves, so I don't believe there's anything stopping me from raising the default back to 10 - except for compilation speed. Our testers have noticed that our libraries are taking longer to compile (it's not huge, but it's like 10%-20% in various example projects). Some of this is necessary because we're implementing more stuff mandated by C++11. I've already implemented a workaround for one thing (allocator_traits) required by C++11, but where we can take a shortcut that's much cheaper to compile and has indistinguishable results. We're not currently aware of other places where we can increase compilation speed - except for _VARIADIC_MAX. Defaulting to 5 results in greater compilation speed for everyone who doesn't need huge tuples/etc. and the people who do need them are "nicely" informed with compiler errors. (I should probably write a blog post about this - I've mentioned in several times in passing, but not in a whole dedicated post.) Defaulting to 10 would allow all code that compiled with VC9 SP1 and VC10 RTM/SP1 to continue to compile with VC11 - but at the cost of slower compilation speed for everyone who doesn't need infinity to be big.
I haven't heard a *whole* lot of grumbling about infinity=5 so my current plan is to leave it that way. If we get a lot of feedback, increasing the default is trivial, so there's plenty of time to change this later.
GoingNative 3: The C++/CX Episode with Marian Luparu
Nov 06, 2011 at 6:04 PMC64> I've not tried myself, but you may want to try to pass a VC9 (VS2008 SP1)'s shared_ptr across module boundaries with a module built with VC10 (VS2010)...If the layout and implementation of shared_ptr of these two different compilers differ, you have crash and burn.
The STL never has and never will guarantee binary compatibility between different major versions. We're enforcing this with linker errors when mixing object files/static libraries compiled with different major versions that are both VC10+, but for DLLs and/or VC9-and-earlier, you're on your own when it comes to following the rules.
See more comments…