Don’t Help the Compiler

Download this episode

Download Video

Description

C++ has powerful rules for dealing with low-level program structure.  Before a program is ever executed, the compiler determines valuable information about every expression in the source code.  The compiler understands exactly how long each object's resources will be needed (lifetime), whether each expression refers to an object that the program has no other way of accessing (rvalueness), and what operations can be performed on each object (type).  Using examples from C++98 through C++14, this presentation will demonstrate how to write code that works with the compiler's knowledge to increase robustness, efficiency, and clarity.  This presentation will also demonstrate the horrible things that happen when programmers think they can do tasks that are better left to compilers.

Day:

1

Code:

004

Embed

Format

Available formats for this video:

Actual format may change based on video formats available and browser capability.

    The Discussion

    • User profile image
      ddrcoder

      Awesome talk, STL. Thanks!

    • User profile image
      STL

      Thanks for watching!  I believe the GoingNative staff will be uploading everyone's slides, but I've also uploaded my slides to my SkyDrive: http://sdrv.ms/14seiJC

      This includes the Bonus Slides that I briefly mentioned (most were cut due to time constraints, a few were specifically written to answer questions).

    • User profile image
      Macaque

      Very interesting! Thanks STL.!

    • User profile image
      cjlove

      Really enjoyed this presentation! Thanks!

    • User profile image
      mark

      Will the videos be available at some point?

    • User profile image
      Ivan

      STL you rock... :) Cool presentation...
      Also congrats and tnx for making that proposal for C++14. You mentioned it already on Core C++ videos but only now I realize how cool little addition it is. :)

    • User profile image
      STL

      Yep! And I didn't even have time to explain how giving it to map/set/etc. enables heterogeneous comparisons, which is something that people have wanted for a long time (however we did not have time to implement it in 2013 RTM).

    • User profile image
      vittoriorom​eo

      Great talk as always.

    • User profile image
      mpusz

      Great talk! However I have one comment.

      As much as I like your trick with delegated constructors on slide #20 I would like to point out that it fixes only one of two problems with the code on slide #17. Unfortunately neither you nor any one else mentioned about the other problem during the talk. The class is copyable which can easily lead to double delete. Delegating constructors will not fix that however unique_ptrs (from slide #19) will. It is yet another reason to use them as first resort solution.

    • User profile image
      sap

      First i want to thank for the great talk, really informative.

      but i have a question, in slide 40 you advised not to use template parameters for the functors (greater<>() in this case) because you could generate bugs when, for example, changing the type used by the vector.

      since the template<class T = void>struct greater {} wont be coming out until c++14 (am i correct with this?) what can we do to avoid these types of errors? for example:

      std::sort(vec.begin(), vec.end(), std::greater<decltype(vec)::value_type>());

      is using a decltype the best way? is a bit too verbose, but i guess it will avoid those bugs in case we change the vec type.

    • User profile image
      STL

      mpusz> The class is copyable which can easily lead to double delete.

      I know - that's why slides 17 through 20 say "Lots of stuff omitted to save space". I didn't have space to depict a deleted copy ctor, deleted copy assign, and public access control. I also didn't have time to mention them.

      > It is yet another reason to use them as first resort solution.

      Agreed.

      sap> wont be coming out until c++14 (am i correct with this?)

      Yeah. Note that greater<> will be available in VC 2013 and libc++ 3.4. (I don't know libstdc++'s status.)

      > is using a decltype the best way?

      You could do that, or you could implement the transparent operator functors yourself.

      Note that the ability to say decltype(expr)::type was added to C++11 very late in its development and VC doesn't support it yet. You can introduce a typedef as a workaround.

    • User profile image
      Mike Marcin

      There is much talk about how awesome std::vector is and I agree mostly.
      However slide 10 illustrates a major shortcoming.

      vector<uint8_t> rgba(PNG_IMAGE_SIZE(img));

      This results in a call to the vector constructor:

      explicit vector(size_type n);
      - Effects: Constructs a vector with n value-initialized elements.
      - Requires: T shall be DefaultConstructible.
      - Complexity: Linear in n.

      Which is unfortunate. It would be much better if we could construct a vector and leave the elements uninitialized. Then we could finally stop using raw arrays.

    • User profile image
      John Dubchak

      STL,

      At "30% light speed", the in-person talk was too quick for my mind to keep up. I am downloading the video and plan to watch it at half-speed to avoid over-saturation of information.

      Thanks for the depth of information.

      John

    • User profile image
      STL

      Mike Marcin: I am deeply opposed to garbage-initialization and I am quite happy to pay the price of setting bits to zero. However, if you really want garbage bits, you should be able to provide a C++11 allocator whose construct() does nothing for PODs.

      John Dubchak: Hopefully the pause button, plus the slide deck, will make things more comprehensible.

    • User profile image
      abm

      STL, that's a great talk!

      About C99, do you guys have plan to implement compiler magic for tgmath.h in VS 2013? So we can finally say that VS is 100% complying with C99 standards once forever! Do you see C11 headers coming to VS next year or in 2015? or 2016 maybe? :)


      OAN, can you guys be the first at Microsoft and implement XPath2 and XSLT2 W3C standards https://casablanca.codeplex.com/workitem/53. Its being a long long time, nobody at Microsoft is getting excited about it.. yet another C99 story :)

    • User profile image
      STL

      abm> do you guys have plan to implement compiler magic for tgmath.h in VS 2013?

      No. 2013 RC was released yesterday, so we can't add features before 2013 RTM. You should not expect new features in post-RTM Updates.

      > So we can finally say that VS is 100% complying with C99 standards once forever!

      Note that 2013 RC/RTM supports some but not all C99 Core Language features.

      > Do you see C11 headers coming to VS next year or in 2015? or 2016 maybe? Smiley

      You'll have to ask Herb about that. C++14 has not yet incorporated the C11 Standard Library by reference.

      > OAN, can you guys be the first at Microsoft and implement XPath2 and XSLT2 W3C standards

      You'll have to ask the Casablanca team about that.

    • User profile image
      Steve

      STL> "Yep! And I didn't even have time to explain how giving it to map/set/etc. enables heterogeneous comparisons, which is something that people have wanted for a long time (however we did not have time to implement it in 2013 RTM)."

      I vote this being in an upcoming c9 video.

      "I know - that's why slides 17 through 20 say "Lots of stuff omitted to save space". I didn't have space to depict a deleted copy ctor, deleted copy assign, and public access control. I also didn't have time to mention them."

      I vote this too being in an upcoming c9 video.

      -

      Slide page 53 ('C++11 20.3.3 [pairs.spec]/8'):
      What is this page about? Can't recall you mentioning it in the video.

    • User profile image
      STL

      The "Bonus Slides" section consists of slides that I had to "cut" due to time constraints. Slide 53 explains something that a few people noticed in slide 33: make_pair() in C++11 is specified as taking (T1&&, T2&&) but returning pair<V1, V2>. This is intentional, not a typo - the Standard has to transform T1 and T2 for the return type. Slide 53 explains what the transformation is, and why it's a good thing.

    • User profile image
      samsam

      @STL:
      You have email at http://channel9.msdn.com/Events/GoingNative/2013/Q-A-Panel

      I assume you do not rss monitor that page.

    • User profile image
      Tomas Zemanovic

      Hey STL. Great talk!
      To avoid the issue you talk about on slide #17 that you recommend fixing by using unique_ptr, I have followed a rule not to do any initialization in a constructor (only set member pointer to nullptr) and in a destructor I only perform delete if pointer is not null. What is your view on this approach?

    • User profile image
      STL

      Tomas Zemanovic> Great talk!

      Thanks!

      > I only perform delete if pointer is not null.

      Note that delete null, delete[] null, and free(null) are all guaranteed no-ops.

      > What is your view on this approach?

      I am opposed to that technique. Constructors exist to acquire resources (that's where Resource Acquisition Is Initialization got its name from), so requiring constructors to be nofail and then providing initialization functions is reimplementing a core language feature in a clunky manner. It is better to allow constructors to acquire resources, just as they do in the Standard Library, and either write one resource manager class per resource, or be very careful when acquiring multiple resources in a constructor. (Centralizing tricky code in a single encapsulated place isn't terrible.)

    • User profile image
      jza

      I wish you had had more time to go through things just a bit more slowly. Very cool talk.

    • User profile image
      mingdx

      Great talk, just same as your other talks on C++. Thanks.

      Those clever uses of template argument deduction are very interesting.  Is it possible to determine the type of container with this technique. say, I have  a function

      template <class C> void what(C& c);

      when c is a map, it prints "map", if c is vector, it prints "vector";

       

    • User profile image
      Mikhail

      Hey, Stephan, thanks for nice talk!

      I wonder, why on slide #26 do you tell to use "return move(p);" instead of just "return p;" reasoning "p has type different from the return type, so no RVO is done"? It is a statement in a return clause, and compiler knows it, why it cannot add implicit move just like in the previous example on slide #25? Why this case is different? Ok, no RVO, I can go along with this. But why explicit move?

      Thanks!

    • User profile image
      STL

      mingdx> Is it possible to determine the type of container with this technique.

      Sure. In your example, C will be vector<T, A> or const vector<T, A>, or map<K, V, Comp, A> or const map<K, V, Comp, A>, etc. You can use <type_traits> to remove any const qualification - that would be "typename remove_const<C>::type", or remove_const_t<C> in C++14/VC 2013 RTM. Then you can write your own type trait to distinguish vectors from maps from other containers (this is not built-in but it is extremely simple to write).

      Mikhail> Why this case is different?

      The Core Language is very, very careful about moving from lvalues. It might be possible to extend the "move when returning" rule to cases where the types differ, but the Evolution Working Group and Core Working Group in the Standardization Committee would need to think very carefully about whether that could be dangerous. (That is somewhat beyond my ability, but I don't immediately see any dangers.)

    • User profile image
      Will

      @STL Great talk, thank you.

      A small remark: I think that many uses of static_cast, notably when used to disambiguate (like `static_cast<const int& (*)(const int&, const int&)>(max)` (slide 34)), could be replaced by "implicit_cast" ( http://stackoverflow.com/a/863761 ) which is safer. It is not in the Standard (I find that's a pity) but for example it is in Boost :) (very simple code, see the link).

      Also I have a question: About slide 19, just after saying that we can use shared_ptr instead of unique_ptr, you added that you "personally prefer using shared_ptr", can I ask you why?

    Comments closed

    Comments have been closed since this content was published more than 30 days ago, but if you'd like to send us feedback you can Contact Us.