Entries:
Comments:
Posts:

Loading User Information from Channel 9

Something went wrong getting user information from Channel 9

Latest Achievement:

Loading User Information from MSDN

Something went wrong getting user information from MSDN

Visual Studio Achievements

Latest Achievement:

Loading Visual Studio Achievements

Something went wrong getting the Visual Studio Achievements

Day 1 Keynote - Bjarne Stroustrup: C++11 Style

Download

Right click “Save as…”

Slides

We know how to write bad code: litter our programs with casts, macros, pointers, naked new and deletes, and complicated control structures. Alternatively (or additionally), we could obscure every design decision in a mess of deeply nested abstractions using the latest object-oriented programming and generic programming tricks. Then, for good measure, we might complicate our algorithms with interesting special cases. Such code is incomprehensible, unmaintainable, usually inefficient, and not uncommon.

But how do we write good code? What principles, techniques, and idioms can we exploit to make it easier to produce quality code? In this presentation, I make an argument for type-rich interfaces, compact data structures, integrated resource management and error handling, and highly-structured algorithmic code. I illustrate my ideas and guidelines with a few idiomatic code examples.

I use C++11 freely. Examples include auto, general constant expressions, uniform initialization, type aliases, type safe threading, and user-defined literals. C++11 features are only just starting to appear in production compilers, so some of my suggestions are conjecture. Developing a "modern style," however, is essential if we don't want to maintain newly-written 1970s and 1980s style code in 2020.

This presentation reflects my thoughts on what "Modern C++" should mean in the 2010s: a language for programming based on light-weight abstraction with direct and efficient mapping to hardware, suitable for infrastructure code.

Follow the Discussion

  • Good!!

  • Always eager to learn from the best. I'm definitely looking forward to watching Bjarne's interesting talk and the other GoingNative 2012 sessions!

  • Looking forward to this exciting session, Rocks!!

  • Yasir KhanYasir Khan

    Looking forward to all the sessions. I am based in Manchester UK, must have checked the time in Redmond USA at least 20 times today :) cant wait.

  • IvanIvan

    We are gonna party like it is C++98 :P

  • Where are the live feed links?

  • KetanKetan

    http://channel9.msdn.com/Events/GoingNative/GoingNative-2012

  • Awesome talk!

  • Where can I access the recorded keynote?

  • You'll be able to access the recorded keynote and indeed all the sessions right here. Charles said it would take about +1 day to do the encoding and then the downloadable video files will be available.

  • RomanRoman

    Where can I download yesterday videos?

  • It was a great lecture! Angel

    But I haven't had the time to watch other speakers. I'll download the 1080p version of talks, since 1080p makes reading the code much a nicer experience.

    EDIT: Charles, would it be possible to also publish the PowerPoint or PDF slides?

  • @undefined:Yes, where are the recorded sessions?

  • MFHMFH

    Had to work during almost all talks, so I'm looking forward to here all these presentations - saw a bit of the first day live but will enjoy the recordings of all presentations soon Smiley. BTW: great selection of speakers: Bjarne, Sutter, Alexandrescu,…

    @STL: great to here that range-base-for-loops will be in VC11.. though I'm a std::for_each-guy so that's not that big of a deal for me.

     PS: looking forward to std::thread-support in VC…

  • STLSTL

    The 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.

  • RuedigerRuediger

    The first qsort Example seems to be broken. I guess it goes to show how bad the API really is.

    void f(char *arr, int m, ...) {
    qsort(arr, m, sizeof(char*), cmpstringp);
    }

    He probably wanted a char *arr[].

    Great talk so far.

    btw. this website should support Unicode in names!

  • bjarnebjarne

    Thanks. Fixed for future uses.

  • vladimirvladimir

    A great talk!
    I believe the 38 slide should read
    shared_ptr<Gadget> p( new Gadget{n} );
    instead of
    shared_ptr<Gadget> p = new Gadget{n};
    The same thing with the 39 slide.

  • I thought the talk on C++11 was great.

  • akhilakhil

    helpful

  • Can someone enlighten me about the syntax on page 62 (and 63) of slides:

    double* f(const vector<double>& v); // read from v return result
    double* g(const vector<double>& v); // read from v return result
    void user(const vector<double>& some_vec) // note: const
    {
    double res1, res2;
    thread t1 {[&]{ res1 = f(some_vec); }}; 
    thread t2 {[&]{ res2 = g(some_vec); }};
    // ...
    t1.join();
    t2.join();
    cout << res1 << ' ' << res2 << '\n';
    }

    Isn't there a type mismatch between f() return and res1?

  • ...

    I make an argument for type-rich interfaces, compact data structures, integrated resource management ...

    light-weight abstraction with direct and efficient mapping to hardware, suitable for infrastructure code

    ...

    I took some sentence from the description of Bjarne description, because I am trying to find ressources, materials tutorials that show how to acheive this. For the previous standart or c++11. Anybody know good reference where i can find this now?

    thanks

  • CharlesCharles Welcome Change

    @undefined: Slides will be released with each session video! Like this one Smiley

    C

  • bryaneddsbryanedds An ​individuali​st is he who is saving himself from all those who are saving the world.

    Oh heck I give up.

  • , Charles wrote

    @undefined: Slides will be released with each session video! Like this one Smiley

    C

    Cool. Now we can see the invisible graph.

    Angel

  • bjarnebjarne

    Yes, having to explain an invisible graph was a bit of a challenge :-)

    Thanks for the comments; corrections will be applied to future versions of the talk.

  • JedrekJedrek

    It is interesting to ask if the software which supposed to show the graphs and the graph itself (i.e. invisible one) was written in C++. I noticed also some problems with fonts on one or two slides.

    According to my experience these are typical problems in all kind of scientific presentations.

    It is hard to believe that it is so difficult to avoid those problems with current technology. The same presentation on one computer looks very different on a different computer only because some other fonts are installed on that computer. In theory it is possible to embed the fonts with the presentation unfortunately this method do not work well in many cases (my own experience).
    The only real solution is to transform the presentation into pdf or use some other software (or use your own computer but in many cases is not possible).
    I saw these problems hundreds times in all kind of conferences and it looks like nobody in the MS Office Team cares about that (since the existence of MS Office).

  • Brian JonesBrian Jones

    The question about an easier way to declare getters and setters, anyone else think than Bjarne was just short of saying "I don't want that crap in my language"? =)

  • Nice. C++ may get bashed a lot, but its creator can certainly deliver a coherent presentation.

  • I would be interested in comments from Mr Stroustrup on these C++ compiler extensions by Microsoft:

    Using Windows Runtime Components in Visual C++

    Specifically,

    1) The use of "Ref" classes

              Person^ p = ref new Person("Clark Kent");

    and their declaration.

     

    2) The use of Platform Strings at the library interface

    using namespace Platform;

    std::wstring wstr1( L"Test" );

    String^ str10 = ref new String(  wstr1.c_str(),   wstr1.length()  );

  • VincentVincent

    Shouldn't there at least be a performance difference between
    sum=0; for(vector<int>::sizetype i=0;i<v.size();++i){ sum+=v[i]};
    sum=0; for_each(v.begin(),v.end(),[&sum](int x){sum +=x;});

    Since the first is calling size() during each loop, while the second (I believe) wouldn't constantly be rechecking the size, similarly to defining a vector<int>::sizetype end=v.size; and checking i<end?
    I am also curious why there aren't at least some run times or something to back up the claim that there is no discernible difference between "several systems and several compilers"?

  • Darren Stevensvirtualperc​eption Darren Stevens

    On my question about getters and setters in the video, I guess that these should be avoided; public data and object members should simply be declared public, despite what I've seen to be a common practice on many projects, and which seems to be promoted in many object oriented languages. 

    Ideally, there would be some way to overload the setting of an object or data "property" if the logic needs to be changed or limits imposed. I have created a Property template class in the past as Bjarne suggested, however, there is no elegant way for the parent class to overload the setter in the aggregated Property<T> member, and the syntax of accessing members of the property too often become property.get().member(), rather than property.member(), which is what you want to write.

    From a language viewpoint, perhaps something like an overloaded "member access operator" would allow library writers to implement a setter or getter later if needed without changing user code. But without this, we suggest that if we need to change logic around setting or getting a member value, make the property private and recompile - we can easily find and update all the usages of the data member to use the new getter or setter.

  • CharlesCharles Welcome Change

    So awesome to have Bjarne posting on C9! Smiley Thank you, sir.

    C

  • @undefined:Darren, here are my thoughts on your question. If you created a wrapper class for each public data member you could overload the assignment operator to perform bounds checking (as well as assignment) and perhaps throw an exception if necessary. That would solve the problem of assigning to a property without a setter. Of course, you would also have to overload all other meaningful operators for that property such as the boolean operators. You would have to repeat all this for each property, which in the end may be more trouble than it's worth. I can't really think of another way to do it, but I also haven't touched C++ in awhile so I could be wrong. Anyway, good luck.

  • ericeric

    I would really love to hear a talk, or read a paper, from Bjarne that discusses when to use OOP, and when to choose Functional or Type programming. For me, finding a balance has always been the most difficult part in software development. There just isn't one right way, but I'd love to hear his thoughts.

    If anyone has any links to anything related that would be wonderful.

  • byungilbyungil

    Nice

  • Darren Stevensvirtualperc​eption Darren Stevens

    For those who are also members of the C++ Software Developers group on LinkedIn, I have started a discussion about what I believe are the most important features of C++ 11, and would love to see feedback and examples of good style that people would like to contribute. See http://www.linkedin.com/groups/Bjarne-Stroustrup-on-C-11-2771729.S.93354359?view=&gid=2771729

  • T TT T

    I watched the video few times.
    I feel like we need some "fresh-minds" in defining what programming should look like, replacing Bjarne.
    They had their era, time to move on.

  • My InterfaceMyI MyI at XBLIG /* :: */ My Interface on XBOX
    I haven't sat in on a lecture in a few years, it came down to a new roof on the house or another semester.  You got me on bloat-ware, so I'll be reading your "The C++ Programming Language, Special Edition" at Safari Books Online.  Thanks for speaking, it was refreshing to see and hear about what you think is important in the field of programming and that coming to grips with best practices is both objective and subjective.
  • pafindepafinde

    My biggest problem with C++ (in big project) are the #includes that square the amount of source to compile (headers are compiled separately for each compilation unit).
    Look how long it takes to compile firefox or KDE :-(
    I think this is were we pay the cost for [over]using templates and/or inline functions.

    Maybe there is something that could be fixed here? Maybe if we break backward compatibility (drop the preprocessor)? It's a pity that those problems were not mentioned here.

  • @pafinde: That's one of the things that modules seek to solve. 

  • BjarneBjarne

    You can see the "invisible" graph in my posted slides.

    I wrote a paper for IEEE Computer Magazine with very similar examples. See the January 2012 issue of Computer or my publications page: www.research.att.com/~bs/papers.html

  • bogbog

    Using !bind(pred, _1) in the first call to stable_partition() in the definition of the gather() function template (around minute 56 of the video) won't compile, will it? (Unless the wrapper object returned from bind() overloads operator!, which I don't think it does.)

    Maybe something like not1(pred) would work, assuming the definition of Predicate contains the necessary typedefs. Or a lambda, of course.

    I also guess removing bind() from the first call will remove it from the second one as well, since it doesn't seem to do much there anyway (I suppose it's there for symmetry reasons).

    That said, the example is excellent.

  • From C++ application development point of view, is there any place for compiler generated iterators in C++ (c# IEnumerable)? Seems like they may be implemented with zero overhead, like lambdas do.

  • I dont see any difference between the example

    Rectangle(int, int, int, int);

    and the 'better' example

    Rectangle(Point, Point);

    Both are understandable only if you use declarative parameter names as it is done with

    Rectangle(Point top_left, Point bottom_right);

    which is equally understandable for me if you write 

    Rectangle(int top_x, int top_y, int bottom_x, int bottom_y);

     

  • bogbog

    @cborgolte: The idea is to convey as much information as possible about program logic and interface semantics through types.

    The example using Point types does a much better job at that than the one using plain ints. As Bjarne explained in the talk, the plain ints could mean a combination of a point and extents, and there's no way to tell just by looking at the function declaration (I can give you another possibility: left side, right side, top side, bottom side). The interface using Point types makes the intent clear.

    Besides, the two points don't need to be top left and bottom right; any decent implementation will accept any pair of opposite corners, in any order, as any two points with different x and y coordinates will uniquely determine a rectangle with the sides parallel to the coordinate axes (at the limit, the coordinates don't need to be different, of course, but we're usually interested in rectangles that haven't collapsed to a line segment or point). In the function implementation, the cost of testing that the two points are really top left and bottom right is about the same as for accepting any combination, so it doesn't make much sense to artificially restrict the interface. That means not using parameter names is even better for the declaration using Point types.

    So, there you have it: an interface that is both more expressive and more flexible - what more could you ask for?

     

  • @bog: Thanks for this detailed answer to my comment.

    I dont want to start nit-picking here. For sure 99.9999% of all programmers (me included) would use both corner points to define a rectangle. But you could also define it by its center point and any other point.

    Or using the second constructor with Point top_left and Box_hw. Even if i would be 99% sure that i know what's meant, if i would read 

    Rectangle(Point, Box_hw);
    I would take a look at the implementation or read the docs to be sure.

    So for me, using declarative parameter names highly improves the readability of interfaces.

  • After a night thinking about this issue I have to correct my first comment.

    Within the meaning of this excellent talk, the examples using Point are the better ones. I was just misled by the different notations for good examples written with parameters and bad examples written without.

    The Point example is better, because it implicates the possibility to use units like it is done by the Speed example.

  • BjarneBjarne

    The general point (sic) about the Point example is that sequences of arguments of the same type is prone to transposition of argument values. I consider it a well established fact that this is a significant source of errors. The implication is that we need to look for remedies. Using a more expressive and specific set of types is one approach.

  • A very good source of infomation..

  • petrymcpetrymc

    Bjarne sir, I truly enjoyed, appreciated, and was influenced by your presentation. One thing that comes to mind is the ability for C++ to write performant, yet secure code.

  • I'm confused at one thing.

    I can understand where he says, shared_ptr and unique_ptr,
    but where he says why use a pointer, and then shows this code:

    void f(int n, int x){
      Gadget g{n};
       // ...
       if (x < 100) throw std::run_time_error("Weird!!");
       if (x < 200) return;
       /...
    }

    I'm  pretty sure C++ wouldn't except that? 

  • I've just run a test, and you can scope a variable like in Java now ^_^

    it would be like this

    void f(int n, int x){
      Gadget g(n);
       // ...
       if (x < 100) throw std::run_time_error("Weird!!");
       if (x < 200) return;
       /...
    }


    Its amazing to see how C++ is catching up with .NET.
    I've always been a C++ guy.

    Thanks again. 

  • BjarneBjarne

    Now? That last f() has worked for about two decades! It's pure C++98.
    The "Gadget g {n};" in the original example, simply used the C++11 uniform initializer syntax, but is otherwise identical.

  • Wow, i must be honoured to get a reply from the man himself.

    Thanks for the heads up Bjarne, C++ is really moving up.

    So I can just pass a object by value by using rvalue references.

    That is soo cool.

    Tom 

  • Chtistopher Yeleightongiecrilj71pl turtlethere

    So, why can’t I read an unsigned char from an input stream?

    When I try to read from "0", I get 060 and not 0 as expected.

    And when I push (unsigned char) 0, I get "\0", not "0" in the output.

  • bjarnebjarne

    (1) Huh? unsigned char c; while(cin>>c) cout<<c<<'\n'; gives exactly what I expect

    (2) The value of (unsigned char)0 *is* 0; not the value of the character '0'

  • Great presentation Bjarne. Honestly I have checked it a few times already Smiley     on the expense of not having watched the other videocasts yet...

    Too bad the Vector vs Linked-List comparison kind of fell short. In spite of the graph-mishap I got inspired and tested it on a few different machines. For small amounts it was virtually the same but as the sets got larger there was a huge difference.It was fun to see - especially since I remember discussing this a couple of years ago (then I failed to see the larger picture).

    Thanks again for the presentation!

     

  • RayRay

    To the guy asking about getters and setters using different get and set functions per class and while still keeping function inlining, this should work.

    template<class OutType, class StoreType, class Controller>
    class Property
    {
    private:
    StoreType data;

    public:
    operator OutType()
    {
    return Controller::get(data);
    }

    OutType operator=(OutType a)
    {
    Controller::set(data, a);
    return Controller::get(data);
    }
    };

    class HPController
    {
    public:
    static int get(int &a)
    {
    return a;
    }

    static void set(int &a, int &b)
    {
    a = b;
    }
    };

    class Man
    {
    public:
    Property<int, int, HPController> HP;
    };

    void PropertyTest()
    {
    Man man;
    man.HP = 7;
    cout << man.HP << "\n";
    }

  • Chtistopher Yeleightongiecrilj71pl turtlethere

    (1) Huh? unsigned char c; while(cin>>c) cout<<c<<'\n'; gives exactly what I expect

    (2) The value of (unsigned char)0 *is* 0; not the value of the character '0'

    1. What exactly do you expect?  Moreover, your thought experiment is incomplete, as you have provided no assumptions for the behavior of (cin >> c).  I am sure that our expectations coincide on assumption that cin is empty  Big Smile
    2. But the text form of (unsigned char) 0 is the string "0", not the character '\0'.
  • Laserbeak43Laserbeak43

    Thanks Bjarne!!!
    I knew I wasn't stupid for wanting readable interfaces!! Hehe

  • @Ray: The problem with that approach becomes when your 'controller' needs to do something a bit more complex and needs the target object's state to decide what to do or needs to notify the target object to do something else upon a change.

    In my experience I've found those cases the primary cases where I actually needed getters and setters.

    So then in that case the Property class template needs to change to be able to contain a controller object which then holds a reference to the target object ( 'Man', in this case ), and the Controller then can not use static methods.  

    But then here is the bloat added.

    So I like Darren's new proposal best - if they are logically publically available properties just leave them as public member variables.  

    In the future, when you realize that you need something more complex, either make them private and add getters and setters and modify the client code, or make a decorator that allows the assignment operator to work with them which calls the real getters and setter behind the scenes.

     

  • achach

    The truth is IOStream treats signed/unsigned chars as characters and not as numbers. Whether this is something to be expected I don't know.

  • DeanDean

    Didn't know I could watch this on the internet.

    I will definitely watch this as soon as I get off.

  • BjarneBjarne

    My suggestion is that when you write a char (short for "character") to an character I/O stream, you should expect to see that character on the output device. It takes quite some alternative learning to expect otherwise.

    PS The "c" in cout, stands for "character"
    PPS "If everything else fails read the manual"

  • LukeLuke

    I was trying to use his units code that was on the slide around 24:00, but the syntax he uses for the following doesn't seem to work with gcc 4.6.2 and -std=c++0x

    using Speed = Value<Unit<1,0,-1>>;

    I've never seen this use of the using directive before. Anybody know what is up with this?

  • @Luke: gcc 4.7 introduces support for template aliases.  I have only 4.6.1 installed... I'll need to upgrade I guess

  • With gcc 4.7, the following works:

    Speed sp1 = Value<Unit<1,0,-1>>(100); // 100 meters / second

    But this does not (operator/ is not defined):

    Speed sp1 = Value<Unit<1,0,0>>(100) / Value<Unit<0,0,1>>(1);

    I guess he left out the part which would define all the arithmetic operators.

  • bjarnebjarne

    Yes, about two pages of things like this

    template<class U1, class U2>
    Value<typename Unit_plus<U1,U2>::type>
    operator*(Value<U1> x, Value<U2> y)
    {
    return Value<typename Unit_plus<U1,U2>::type>(x.val*y.val);
    }

    and this

    template<class U1, class U2>
    struct Unit_plus {
    typedef Unit<U1::m+U2::m,
    U1::kg+U2::kg,
    U1::s+U2::s
    > type;
    };

    You can make that prettier in C++11, but I was using an old compiler (then), so I used old-fashioned, but effective, metaprogramming.


  • I like this one. 

  • DavidDavid

    !bind comes from boost.


    "Using !bind(pred, _1) in the first call to stable_partition() in the definition of the gather() function template (around minute 56 of the video) won't compile, will it? (Unless the wrapper object returned from bind() overloads operator!, which I don't think it does.)"

  • OlivierOlivier

    - from decades, code was been easy to learn first, because you were just need a few terms for programming. And you were done all things with that.

    - Now, you need , you must use Interfaces , typedef specifics, classes globally existing in a namespace (like .NET) and you must know how you name it.
    Yes, a box it's ok . This is a simple box. But, Box_hw ? how do you spell it ? You need now what you want to do but name it !

    Is it more difficult for programmers ? No . Is it more difficult to remember the names ? No
    It it always difficult to remember for beginners. But, if you are a beginner, engineer, you just need to remember all classes. For example, even google couldn't help you if you want a bicycle and you don't know how you spell a bicycle.
    Now, differences between engineers : a few people know all classes ? well, but it's not very realistic.

    Second, i love when i can be a C++ programmer since i know how to program in Java. That is in a good spirit.

    Third, i love when he said "who does the delete ?" . Many bugs come from the bad documentation or a left program.

    And else about Copy ? Not copy ? well, you can choice. You need to choice and need to say in the documentation that you can copy or not (thread safe ?).

    After, it explains you should have use a Vector and not a List to insert incrementally your data because true OO type is a chained list. That is the difference and a time consuming with .NET List insertion. But, it's implementation dependent. You should know the implementation now.

    Low level is should be not use : use standard templates instead. That's very C++ !

Remove this comment

Remove this thread

close

Comments Closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums,
or Contact Us and let us know.