Slashdot Mirror


Biggest Changes In C++11 (and Why You Should Care)

Esther Schindler writes "It's been 13 years since the first iteration of the C++ language. Danny Kalev, a former member of the C++ standards committee, explains how the programming language has been improved and how it can help you write better code."

57 of 385 comments (clear)

  1. 13 years? by undulato · · Score: 2, Interesting

    I could've sworn I was using it before then.. perhaps it was all just a bad dream?

    1. Re:13 years? by elsurexiste · · Score: 2

      A post under you already explained it: it refers to the first ISO standard for C++. And yeah, I thought the same thing: "Really? Only 13 years?"

      --
      I rarely respond to comments. Also, don't ask for clarifications: a brain and Google are faster, believe me!
    2. Re:13 years? by crow_t_robot · · Score: 3, Informative

      After years of development, the C++ programming language standard was ratified in 1998 as ISO/IEC 14882:1998

      C++ didn't exist as a standardized language till 13 years ago. It was in development before then.

    3. Re:13 years? by vidnet · · Score: 4, Funny

      What struck me was that C++ got lambda expressions before Java did!

    4. Re:13 years? by Lord+Lode · · Score: 3, Informative

      The previous C++ standard, C++98, is 13 years old, as the name implies.

    5. Re:13 years? by utahjazz · · Score: 2

      It was developed by Bjarne Stroustrup starting in 1979

      the C++ programming language standard was ratified in 1998

      So you're saying the "first iteration" took 19 years. You must use the word "iteration" differently at your shop than we do at mine.

    6. Re:13 years? by StackedCrooked · · Score: 2

      He started coding in 1979 and waited until 1998 to build it?

    7. Re:13 years? by rjstanford · · Score: 3, Funny

      Now that's waterfall development!

      --
      You're special forces then? That's great! I just love your olympics!
    8. Re:13 years? by sgt+scrub · · Score: 2

      No. He used templates and built it statically. It finished building on Unix in 81. The compiler didn't finish on windows until 98 because of all of the constant win api changes.

      --
      Having to work for a living is the root of all evil.
    9. Re:13 years? by Carewolf · · Score: 2

      C++ have had lambda expressions for more than a decade, they were just really inconvenient to declare and use. Now it is easier.

    10. Re:13 years? by koreaman · · Score: 2

      i've never heard of such a thing. Then again I'm not (primarily) a c++ guy. Care to provide an example of lambdas before C++ 2011?

    11. Re:13 years? by siride · · Score: 4, Insightful

      I have to lol at the "constant win api changes" statement. The Win API bends over backwards for backwards compatibility. In Unix, especially Linux, outside of POSIX (which is fairly limited in functionality), backwards compatibility is almost a 4 letter word.

    12. Re:13 years? by TheRaven64 · · Score: 3, Funny

      ModParentUpEx64!

      --
      I am TheRaven on Soylent News
    13. Re:13 years? by RoverDaddy · · Score: 2

      I hope your intent is to point out how the WIN32 API made sure that ModParentUp did not stop working when ModParentUpEx was added later, and again when ModParentUpEx64 was added more recently.

      --
      RETURN without GOSUB in line 1050
  2. 13 years? by Meneth · · Score: 4, Informative
    C++ has been around for at least 28 years. From Wikipedia: "It was renamed C++ in 1983."

    The article is probably referring to the first finished C++ ISO standard, 14882:1998. Hardly the "first iteration" of the language.

  3. Re:Still playing catch-up to C#. by lxs · · Score: 2

    Yeah but this one goes to eleven!

  4. Nice but... by genjix · · Score: 3, Interesting

    Would love to use these features in the new C++, but unfortunately none of the major compilers support the new for-syntax, in class initialization, deleting members and explicit specification of base class methods.

    Also I totally don't understand why enum class no longer casts to ints... it totally makes using binary flags impossible unless I revert back to using the old style enums. But then I need to do the ugly namespace myenums { enum myenum { foo = 4, bar = 8 ... }; } hack which makes nesting inside classes impossible -_-

    1. Re:Nice but... by Anonymous Coward · · Score: 2, Interesting

      Would love to use these features in the new C++,...

      Why? What is it about these new features that will make your job easier, your code more reliable, and easier to be maintained? Or do you just want to use those features because they're "new" - for C++ that is?

      As a long time C++ guy (Borland C++ days), I look at some of these features and think "so what?" (Lambda functions, please.) I'll probably never use them. IMHO the last truly useful feature that C++ added was Templates which lead to the STL and made my life much easier - after I got the hang of the way the STL implemented things such as "iterators" and the gotchas associated with them.

      Event hen, it drove me nuts when I had to maintain code by a C++ coder who just wanted to use features for the sake of using them - like all the classes that used one dtaa type and would always use one data type being a Template class - arrrrrghh! (All that code and overhead for nothing!) Coder: "It was a cool thing to do!"

      I tell ya, with all these features being added, I just want to say "Fuck it! Gimme an assembler, a cave, a generator, and a computer!" and grow my hair and fingernails out and laugh manically at random times.

    2. Re:Nice but... by Arlet · · Score: 3, Insightful

      Bitfields are not as flexible when you want to change several different bits (belonging to different fields) in a word using a single write.

    3. Re:Nice but... by mmcuh · · Score: 5, Informative

      GCC, which is probably the most used C++ compiler, supports the new for-syntax since 4.6, deleted member functions since 4.4, and explicit virtual overrides in the 4.7 development series.

    4. Re:Nice but... by DrXym · · Score: 4, Insightful

      Templates are fine for little classes but they got so abused by STL that it was not uncommon to see trivial syntax errors turn into enormous cryptic compiler errors spanning multiple lines of nested templates and typedefs, half of whom you'd never heard of. After poring over this enormous error for minutes or longer you might eventually discover you missed a * off some declaration.

    5. Re:Nice but... by TheRaven64 · · Score: 2
      At least one feature in C++ 2011 (no, not C++11, they decided to make the name Y2K compliant this time) is useful: the auto type. If you've ever written a loop using foo::bar::iterator and had to split the loop over two lines because the iterator type is so long, you'll appreciate being able to do:

      for (auto i=collection.begin(), e=collection.end() ; i!=e ; ++i)

      Strong typing without type inference is just a stupid idea that should never have been allowed in a production language.

      --
      I am TheRaven on Soylent News
    6. Re:Nice but... by JohnnyBGod · · Score: 3, Interesting

      What so wrong with "const int SOME_BINARY_FLAG = 0xff00ff"?

    7. Re:Nice but... by mmcuh · · Score: 2

      If your collection type has .begin() and .end() you can do

      for (auto& v : collection) { ... }

      ...and 'v' will be a reference to the value_type of the collection that refers to the element currently being iterated over. It's basically short for

      for (auto i = collection.begin(); i != collection.end(); ++i) { auto& v = *i; ... }

      You can of course also use it without the &, but then you make a local copy of every element.

    8. Re:Nice but... by Kevin+Stevens · · Score: 2

      This is definitely true. Concepts were supposed to fix this problem, but they were booted out at the last minute. Like most compiler errors though, you start associating those walls of text with common errors after a few times. STL isn't the worst offender by far in my opinion though, boost is. Most of Boost is hard to really consider C++ anymore, its template meta programming. C++ is there in the core, but if you show a circa 1998 (IE pre-templates) developer most boost libraries, they probably wouldn't recognize it as C++.

    9. Re:Nice but... by Suiggy · · Score: 2

      C++11 has fixed that with the inclusion of the constexpr keyword, which allows you to define compile time constants, functions, and expressions.

      For example:
      constexpr uint32_t some_binary_flag = 0x8000000u;
      constexpr int add(int x, int y) {
              return x + y;
      }

    10. Re:Nice but... by Mr+Z · · Score: 2

      You can do this in C++ pretty easily by overloading the bitwise OR operator on the enum. Thus, when you have an enum type that you know is safe to manipulate as a set of orthogonal (or mostly orthogonal) bitfield values (such as the macros that define flags for open(), for example), you can add the appropriate "operator|" to work on that type.

      Example:

      #include <iostream>

      using namespace std;

      enum foo
      {

      • FRED = 1,
        WILMA = 2,
        BARNEY = 4,
        BETTY = 8

      };

      foo operator | (foo lhs, foo rhs)
      {

      • return (foo)((unsigned)lhs | (unsigned)rhs);

      }

      int main()
      {

      • foo bar = FRED | WILMA | BARNEY | BETTY;

        cout << bar << endl;

      }

      This prints "15".

      As I recall, enums can have the integer value of any of the enums defined in the set, or any of the bit patterns formed by ORing any combination of members of the enum set. So, this is entirely legit code.

    11. Re:Nice but... by WWE-TicK · · Score: 2

      Dunno about you, but I find lambda's extremely useful. It lets me use Boost's signals and slots without using that butt ugly boost bind() function. I also like using them to do nested functions like you could in Pascal. The new overloaded meaning for the auto keyword is also a pretty awesome addition. The compiler I use the most these days (VC 2010) doesn't do typesafe enums yet, but I see myself using that a lot when it comes too.

    12. Re:Nice but... by TheRaven64 · · Score: 2

      Speaking as someone who works on a C++ compiler - you're entirely wrong, for several reasons. The const qualifier means that the compiler can assume that it doesn't change. It can, in the first constant propagation pass, replace all loads of the constant with its value, and can then remove the memory allocation if it's static qualified, because it has no users. In fact, if it's static qualified and not const then, at a higher optimisation level, most compilers will work out that it never has its address take and there are no stores and do constant propagation there as well.

      In C and C++, however, this is irrelevant because a const variable like this won't even be emitted in the IR. It will be classed as an integer constant expression in the front end. The front end needs this logic for several reasons. With C++98, for example, VLAs are not allowed, so the compiler needs to do constant propagation in the front end for expressions like:

      int foo[someConst];

      The compiler must be able to determine that this is an integer constant expression, which both C and C++ specs define in excruciating detail. Any vaguely recent compiler will include a static evaluator for integer constant expressions, so something like 4*someConst will be evaluated at compile time if someConst is declared as const int.

      You will save a tiny bit of compiler memory if you use a macro, because then the preprocessor will just insert the constant value, but that's it, and you lose a lot in terms of tool support (doxygen and friends handle constants better if they're really constants, not macros).

      --
      I am TheRaven on Soylent News
  5. Cruft removed? by kikito · · Score: 4, Insightful

    I really like that they added new stuff to the language but ...

    Have they *removed* anything at all from it? That's the only way I could get interested in that language again.

  6. But... by DeathToBill · · Score: 5, Insightful

    This is news for nerds. Stuff that matters. I thought /. abandoned this stuff ages ago...

    --
    Slashdot - News for Nerds, Stuff that Matters, in ISO-8859-1 Has just realised that beta makes this signature redundant
  7. Biggest Change? by hal2814 · · Score: 4, Funny

    C++ goes all the way to 11. It's one louder than other languages.

  8. Re:C++0x by LighterShadeOfBlack · · Score: 3, Insightful

    C++0x is C++11. C++0x was a placeholder name until they actually knew what year it would be finalised.

    --
    Spelling mistakes, grammatical errors, and stupid comments are intentional.
  9. Alternative syntax by Errol+backfiring · · Score: 2

    If the "alternative syntax" from PHP were allowed, the language could even become legible. What I see is still a write-only language.

    --
    Nae king! Nae laird! Nae yurrupiean pressedent! We willna be fooled again!
    1. Re:Alternative syntax by Mystra_x64 · · Score: 2

      I fear they day C++ guys will learn that Unicode has so many previously unused special symbols that can be reused to mean something in C++.

      --
      Quick way to get 30% Funny 70% Troll: defend Opera browser on /.
    2. Re:Alternative syntax by yarnosh · · Score: 2

      LOL. PHP as a comparison for readability. $That's->rich();

    3. Re:Alternative syntax by TheRaven64 · · Score: 3, Informative

      Would it be that painful to add a lambda keyword?

      Yes, actually. Adding keywords to a language is problematic, because lots of existing code will use them as identifier names. If you add a lambda keyword then you break any existing code that contains a variable, function, or type called lambda. C99 had some ugly hacks to get around this for bool: the language adds a __bool type, and the stdbool.h type adds macros that define bool, true, and false in terms of __bool.

      --
      I am TheRaven on Soylent News
  10. See wikipedia by Anonymous Coward · · Score: 3, Informative
  11. Re:Still playing catch-up to C#. by rennerik · · Score: 5, Interesting

    Your comment caught some flack, but I couldn't help but make a similar observation as I read the spec. It seems that they are adding a lot of stuff to C++ that exists in C# (lambda expressions, delegated constructors, automatic deduction, initialization syntax, a dedicated null keyword, etc).

    Of course, they added a bunch of stuff that's also NOT in C# (since it's not necessary in a high-level language like C#), but I am glad that they are revamping C++ to incorporate some higher-level functions. Now we just have to wait for compilers to start adopting the new spec...

  12. Re:C++0x by geminidomino · · Score: 2

    You know, like how Clash at Demonhead and Mega Man 2 took place in "200X!"

    And it looks like they missed their worst-case deadline by 2 years!

  13. Design by Committee by Alistair+Hutton · · Score: 2

    I love had back in the day C++ advocate sneered at ADA due to that fact that ADA was "designed by committee". Now C++ is the ultimate example of a design by committee language. And that committee is huge.

    --
    Puzzle Daze is now my job
  14. Does TFA actually explain things? by SanityInAnarchy · · Score: 3, Insightful

    It's been awhile since I've had to do any C++, so maybe I'm just missing something, but it seems like either there's a lot of retarded functionality here, or there's a lot of TFA which introduces a feature, even motivates it, but doesn't actually explain what the new version looks like. For example, with "Rvalue References":

    void naiveswap(string &a, string & b)
    {
    string temp = a;
    a=b;
    b=temp;
    }
    This is expensive. Copying a string entails the allocation of raw memory and copying the characters from the source to the target...

    Ok, first, what? I thought standard library string implementations were supposed to be efficient, and include some sort of copy-on-write semantics, which would (I would hope) make the above a shuffle-pointer-around instruction instead of a copy-data-around instruction.

    Second, here's the newer, better syntax:

    void moveswapstr(string& empty, string & filled)
    {
    //pseudo code, but you get the idea
    size_t sz=empty.size();
    const char *p= empty.data();
    //move filled's resources to empty
    empty.setsize(filled.size());
    empty.setdata(filled.data());
    //filled becomes empty
    filled.setsize(sz);
    filled.setdata(p);
    }

    Regarding the first comment, no, I really don't, unless the point is that this is what the code for "moving" would look like if implemented in older versions of C++. But also:

    If you&rsquo;re implementing a class that supports moving, you can declare a move constructor and a move assignment operator like this:
    class Movable
    {
    Movable (Movable&&); //move constructor
    Movable&& operator=(Movable&&); //move assignment operator
    };

    Ok, cool... But where is this used in the "moveswapstr" example? Does this make the "naiveswap" example automagically faster? Or is there some other syntax? It doesn't really say:

    The C++11 Standard Library uses move semantics extensively. Many algorithms and containers are now move-optimized.

    ...right... Still, unless I actually know what this means, it's useless.

    It looks like there's a lot of good stuff here, and the article is decently organized, but the actual writing leaves me balanced between "Did I miss something?" like the above, and enough confusion that I'm actually confident the author screwed up. For example:

    In C++03, you must specify the type of an object when you declare it. Yet in many cases, an object&rsquo;s declaration includes an initializer. C++11 takes advantage of this, letting you declare objects without specifying their types:
    auto x=0; //x has type int because 0 is int
    auto c='a'; //char
    auto d=0.5; //double
    auto national_debt=14400000000000LL;//long long

    Great! Awesome! Of course, this arguably should've been there to begin with, and the 'auto' in front of these variables is still annoying, coming from dynamically-typed languages. But hey, maybe I can write this:

    for (auto i = list.begin(); i != list.end(); ++i) ...

    Instead of:

    for (std::list<shared_ptr<whatever> >::iterator i = list.begin(); i != list.end(); ++i) ...

    It's almost like C++ wanted to deliberately discourage abstraction by making it as obnoxious as possible to use constructs like the above. Anyway, that's what I expected the article to say, but instead, it says this:

    Instead, you can declare the iterator like this:
    void fucn(const vector<int> &vi)
    {
    vector<int>::const_iterator ci=vi.begin();
    }

    --
    Don't thank God, thank a doctor!
    1. Re:Does TFA actually explain things? by siride · · Score: 2

      The article messed up in a number of places as you surmise. You can use auto in for-loops. I don't know why the example didn't show that properly (I was scratching my head).

      As for the swap example, what ends up happening is that with move semantics, you can go back to using the naive version, but it will actually be efficient because under the hood, it uses the rvalue references instead of copying. It will behave is if it were written using all that "pseudo-code" (don't know why he called actual code "pseudo-code"), but without all the horror.

    2. Re:Does TFA actually explain things? by neonsignal · · Score: 2

      Ok, first, what? I thought standard library string implementations were supposed to be efficient, and include some sort of copy-on-write semantics, which would (I would hope) make the above a shuffle-pointer-around instruction instead of a copy-data-around instruction.

      The string implementation is just an example. The current problem is that it is difficult to implement move semantics without having a special case for every class. The introduction of rvalue references enables a class to implement both copy and move semantics in a way that lets other classes transparently move the objects around. The move semantics are that the content is copied but the original need not be preserved (since often the original is a temporary). It enables other code (template libraries for containers and algorithms as an example) to be significantly more efficient.

      Ok, cool... But where is this used in the "moveswapstr" example? Does this make the "naiveswap" example automagically faster? Or is there some other syntax? It doesn't really say:

      Unfortunately parts of the article appear to have been completely munged. It looks like some of the angle brackets didn't get turned into entities, and the html parsing has just swallowed up chunks. So I can understand your confusion.

      ...right... Still, unless I actually know what this means, it's useless.

      It means that STL functionality can be made as fast as possible, since the copying of temporaries was one of the few potential places for improvement. This doesn't make require large changes when you are using the STL from the outside, apart from defining move semantics for your item classes if you wish to take advantage of these improvements.

      ...what? Am I missing something, because this doesn't seem to be about type inference at all. Did we switch to another topic without me noticing? Nope, it continues:

      The second part of the type inference section is not about using auto, but about declaring a type from an expression (rather than just defining it from another type). This is can be useful in a statically typed language, especially in templates where it might be difficult to indirectly access types.

      If I'm alarmed, it's because C++ was already bloated from the first attempt at this -- backporting objects and exceptions to C.

      If by bloated you mean a rich feature set that takes time to learn, then yes. If by bloated you mean a syntax that is sometimes convoluted because of the need for backward compatibility, then yes. But I'm not sure if this is what you mean. The design of C++ was deliberately done to maintain the performance and efficiency of C. Adding objects has no effect on that (apart from a single pointer indirection in some circumstances, and an additional pointer where a hierarchy has virtual methods). Exceptions are of zero impact if you choose not to use them, and even if you do, are inefficient only when thrown. C++ does not force you to use all of the different constructs; there are many cases where it is quite sensible to use a subset (such as in embedded programming).

      as these are mostly taking the good ideas from other languages and backporting them to C++

      I think you'll find that all languages borrow ideas for each other, and C++ is no exception. But a lot of these ideas have been on the table for many years now, it isn't like they are that new in the C++ world. It is just that C++ is an important language, and no-one wants to break it, or introduce poorly thought out features that we will be stuck with. C++ doesn't have the luxury of redefining the language completely, it is both a strength and a weakness.

    3. Re:Does TFA actually explain things? by Eponymous+Bastard · · Score: 2

      Second, here's the newer, better syntax:

      void moveswapstr(string& empty, string & filled)
      { //pseudo code, but you get the idea

      size_t sz=empty.size();

      const char *p= empty.data(); //move filled's resources to empty

      empty.setsize(filled.size());

      empty.setdata(filled.data()); //filled becomes empty

      filled.setsize(sz);

      filled.setdata(p);
      }

      Regarding the first comment, no, I really don't, unless the point is that this is what the code for "moving" would look like if implemented in older versions of C++.

      Yes, that is what the code looks like without move constructors. That has nothing to do with C++11, and yes, it's really ugly.
      This that follows is the declaration (not implementation) of a move constructor.

      If you&rsquo;re implementing a class that supports moving, you can declare a move constructor and a move assignment operator like this:
      class Movable
      {
      Movable (Movable&&); //move constructor
      Movable&& operator=(Movable&&); //move assignment operator
      };

      Ok, cool... But where is this used in the "moveswapstr" example? Does this make the "naiveswap" example automagically faster? Or is there some other syntax? It doesn't really say:

      Now you can do
      Movable foo = bar();
      and it'll call the move constructor rather than the copy constructor when constructing foo. The advantage is important. For example, in the case of a string or a vector you don't copy the contents with the copy constructor just to delete the original when the rvalue goes out of scope. There is a way to force the call to the move assignment, which you could use to force the naive swap to move data from one object to another rather than copy/destroy the data, so you end up with three lines of clean code (I don't recall the syntax now, but it's not that different)

      The C++11 Standard Library uses move semantics extensively. Many algorithms and containers are now move-optimized.

      ...right... Still, unless I actually know what this means, it's useless.

      Nope. For example, when vector grows its storage it currently copies all the objects from the old to the new storage and then destroys the old. Now it'll automatically notice the move constructors and move the data, leaving old objects empty. You get the performance advantage just by implementing a move constructor.

      And since the standard library classes now have move constructors you get this for free for any vector<string> or vector<vector<foo>> or whatever without changing your code.

      It looks like there's a lot of good stuff here, and the article is decently organized, but the actual writing leaves me balanced between "Did I miss something?" like the above, and enough confusion that I'm actually confident the author screwed up. For example:

      In C++03, you must specify the type of an object when you declare it. Yet in many cases, an object&rsquo;s declaration includes an initializer. C++11 takes advantage of this, letting you declare objects without specifying their types:
      auto x=0; //x has type int because 0 is int
      auto c='a'; //char
      auto d=0.5; //double
      auto national_debt=14400000000000LL;//long long

      Great! Awesome! Of course, this arguably should've been there to begin with, and the 'auto' in front of these variables is still annoying, coming from dynamically-typed languages. But hey, maybe I can write this:

      for (auto i = list.begin(); i != list.end(); ++i)

    4. Re:Does TFA actually explain things? by Nimatek · · Score: 2

      even better:
      std::vector<int> vi;
      for(int& i : vi) ...

  15. Re:Still playing catch-up to C#. by Waffle+Iron · · Score: 4, Insightful

    The saddest part about this whole C++0x ordeal is that they're still just playing catch-up to C#.

    True. In particular, C++ is light years behind C# in patent FUD. And C++ hasn't even started work on requirements for a 100MB "managed environment" for users to install before running their apps. Nor have C++ developers chosen a monkey species after which to name its 2nd-class-citizen cross-platform implementation.

  16. Re:Looks cool... by compro01 · · Score: 2

    GCC has it mostly implemented (the new concurrency features remain MIA along with a few other bits) already, including the variadic templates the GP mentions.

    http://gcc.gnu.org/projects/cxx0x.html

    --
    upon the advice of my lawyer, i have no sig at this time
  17. Why is a garbage collector even needed? by ifrag · · Score: 3, Insightful

    What is the big fuss about getting a garbage collector anyway? Why does it even matter? Good C++ code shouldn't need a garbage collector. If memory was allocated within an object then the destructor should be taking care of it. And with shard_ptr (which people should start using) it's taken care of within there anyway. Is this wanted so everyone can start coding sloppy C++ and forget about the delete calls? I suppose for those using some 3rd party library that behaves poorly and is totally out of your control it could be nice to stop that from leaking all over. Still, it should have been done right in the first place.

    I suppose there might be some argument for preventing excessive memory fragmentation. Is there some other benefit to having one?

    --
    Fear is the mind killer.
  18. Re:Still playing catch-up to C#. by pkinetics · · Score: 2

    In fact, Windows Vista and 7 already come with .NET pre-installed, so there's no need to download anything to run a .NET app.

    Cause I really enjoyed the latest .net Framework 3.5 and 4 security updates that was nearly 400 MB... Thank you MS!

  19. Re:Still playing catch-up to C#. by luis_a_espinal · · Score: 2

    It's /. after all :/

  20. Re:Still playing catch-up to C#. by Raenex · · Score: 2

    Cause I really enjoyed the latest .net Framework 3.5 and 4 security updates that was nearly 400 MB... Thank you MS!

    I also enjoyed the way it spent over an hour pre-compiling assemblies during the update. Granted, it was on an old machine, but it still would have been ridiculously long on a modern one.

  21. Re:Nice but... but nothing. They are useful. by luis_a_espinal · · Score: 2

    Would love to use these features in the new C++,...

    Why? What is it about these new features that will make your job easier, your code more reliable, and easier to be maintained? Or do you just want to use those features because they're "new" - for C++ that is?

    As a long time C++ guy (Borland C++ days), I look at some of these features and think "so what?" (Lambda functions, please.) I'll probably never use them. IMHO the last truly useful feature that C++ added was Templates which lead to the STL and made my life much easier... I stopped reading at this point... .

    Let me stop you right there for a second. Proper utilization of lambdas and closures pretty much make a lot of design patterns (template, strategy, visitor, for example) unnecessary in many contexts. This obviously will have an impact in how you write/use templates. Furthermore, lambdas and closures help with shrinking class hierarchies even further than delegation alone.

    Yes, we had functors before, but now you neither need to define functors classes/structs defining 'operator()', nor have to invoke new on them. That is substantially less typing to achieve the same without loss of generality, semantics or performance. We know from industrial evidence across multiple programming languages (or you should know) that this type of facility, when used properly, reduce complexity and the introduction of new bugs. It helps you focus more on the algorithms at hand without worrying about the boiler-plate that it is needed for its setup.

    . This might look trivial in contrite pedagogical examples such as the one found in the wiki section of C++0x#lambdas found here. However, with real algorithms, one typically have to employ more than one functor. That's where the brevity of lambda expressions pay.

    What is happening to you is that you have never done actual work with a language that supports lambdas. And as such, you cannot even imagine how these thing alone (when used appropriately) make code cleaner, and more bug-free.

    In the end, you will know this until you use them in work/real-life scenarios. Until then you only have an opinion based on subjective feelings, not from-the-trenches facts. Give them a HONEST, laborious, nontrivial try, if not in C++ at least in some other, non-trivial work on another programming language, and try the same algorithms without them.

    After the exercise, you might still think they are useless (and I would still think you are wrong). But at least you will have a hands-on basis for your opinion (as opposed than just puffed air.)

  22. Re:C++ still not attractive to me by David+Greene · · Score: 2

    But... until then, I honestly don't think there is anything really worthwhile I could do in c++ that I can't do in c

    RAII. That's a tremendously important idiom that simply cannot be expressed in C.

    When I depend on the compiler to write part of the code for me, I'm going to get mediocre performance from a one-size-fits-all model without any real option to do anything about it.

    One can always write "C-like" code in C++ but the result will probably exhibit worse performance. Compilers are actually quite smart. It's often programmers being "helpful" to the compiler that screw things up. A classic example is using unsigned integers for loop counters. No, the compiler actually doesn't care that it can "see" the loop counter will never be less than zero but it absolutely does care that it might wrap around due to overflow.

    --

  23. I stopped caring about C++... by dargaud · · Score: 2

    ...in 1995 when I saw there was nothing of interest in it. If I want to do system level stuff, I'll use C. If I want to do object programming, I'll use Java and/or Go. I don't see the need for a language that mixes both except as a confusing and hard to maintain broth. Do you pass your food through a mixer before you eat it ?

    --
    Non-Linux Penguins ?
  24. Re:C++ still not attractive to me by fyngyrz · · Score: 2


    RAII. That's a tremendously important idiom that simply cannot be expressed in C.

    RAII is not important to me and does not implement anything I can't do myself, with extremely fine grained control. To "express" this functionality, I check my allocations, I check my return codes and states, I make sure I provide same, I only do new things based on the known state of things I've already done, and I set up state-testing, abort-capable monitors for operations that might conceivably go open-ended. I try really, really hard to never use other people's code for which I don't have control of the source. Then I test the living heck out of things. And this all leads to release-level programs that don't die by exception in the first place, therefore eliminating the need for a program level mechanism to "save" me due to exceptions.


    Compilers are actually quite smart.

    You know, I hear that a lot, but looking at the code the compilers actually generate... it's not evidently the case. Concrete example: I am presently in the middle of a very large image processing project which uses the GCC compiler for objc and c. I have had many occasions to look at the generated code for both idioms, and it is *terrible*. Constant reuse of single registers, as if the CPU only *had* one or two usable registers; thrashing variables on and off the stack, failure to optimize simple shifts and divides of integers... the kindest thing I can say about the GCC compiler is that the code works. It *certainly* doesn't produce good or "smart" code. Writing in assembly, I could run rings around it without ever breaking a sweat.

    Recently, I had occasion to dissemble and patch a bug Apple had left around in the launchd code for Leopard (10.5.) Even if you assume I'm using GCC poorly, one would think that Apple might be a little better at it, yes? Well, the same thing was strongly evident there: register resuse / register wasting, stack thrashing, basically failure to optimize and failure to utilize.

    So while I'll certainly grant you that theoretically speaking, compilers could do a good job than a competent assembly programmer, it's not clear, at all, that they actually do a better job than a competent assembly programmer. The evidence I've seen recently, after many years of compiler development, is entirely the other way.

    --
    I've fallen off your lawn, and I can't get up.
  25. Re:C++ still not attractive to me by David+Greene · · Score: 2

    You know, I hear that a lot, but looking at the code the compilers actually generate... it's not evidently the case. Concrete example: I am presently in the middle of a very large image processing project which uses the GCC compiler for objc and c.

    gcc is not a terribly good optimizing compiler, particularly for things like image processing. Try the same code with the Intel compiler or PGI.

    Constant reuse of single registers, as if the CPU only *had* one or two usable registers

    There's a register-pressure tradeoff being made here. Reusing registers like this lowers the register pressure of the code, reducing spilling. The other extreme is to round-robin the register allocator which allows more scheduling freedom at the cost of inducing more spilling.

    thrashing variables on and off the stack

    Register allocation is a hard problem. It's NP-complete. Can one "eyeball" some asm in specific cases that will outperform the compiler? Sure. But over a large amount of code, a good compiler will win and will save the programmer time.

    --