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

385 comments

  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 Anonymous Coward · · Score: 1, Funny

      Compiling!

    8. 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!
    9. Re:13 years? by Anonymous Coward · · Score: 1

      No, that's glacial. :)

    10. Re:13 years? by Hognoxious · · Score: 1

      So you're saying the "first iteration" took 19 years.

      Nope, the zeroth iteration.

      --
      Confucius say, "Find worm in apple - bad. Find half a worm - worse."
    11. 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.
    12. 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.

    13. 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?

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

    15. Re:13 years? by Carewolf · · Score: 1

      Before you object that this is not the same as a "true" lambda expression, let me just point out, that this what a "true" lambda expression does behind the scene. Compiled there is little or no difference, though native lambda expressions would have better type-casting and type-safety. It is hard to simulate a good type-system using C++ classes.


      struct Lambda {
            int arg1, arg2; // arguments
            Lambda(int arg1, int arg2) : arg1(arg1), arg2(arg2) {}; // bind arguments
            int operator() const { return arg1 + arg2; } // function call
      }

      int main() {
            Lambda f(a,b);
            int c = f(); // c = a +b
      }

    16. Re:13 years? by tiddlydum · · Score: 1

      boost lambda?

    17. Re:13 years? by koreaman · · Score: 1

      "Lambda functions" means syntactic sugar for a certain variety of first-class function. This is a bit like saying every language has operator overloading because one can write a function called Plus.

    18. Re:13 years? by the_greywolf · · Score: 1

      He's referring to the fact that the C++11 lambda syntax is sugar for functors - simple classes with an overloaded operator().

      Boost's Lambda library constructs functors with a rather bare syntax as well, though it's more error-prone and difficult to use.

      --
      grey wolf
      LET FORTRAN DIE!
    19. Re:13 years? by fahrbot-bot · · Score: 1

      C++ have had lambda expressions for more than a decade,...

      And LISP has had them since the early 1960's.

      --
      It must have been something you assimilated. . . .
    20. Re:13 years? by TheLink · · Score: 1

      So when is someone going to post a low level description of "what a true lambda expression does behind the scene" on x86 processors? :)

      Being easier to type and more concise makes a big difference. Often what the programmer has to do in front of the scene is more important to the programmer than what the computer has to do behind the scene ;).

      If there's no difference then there's no difference between using one word/symbol and using a whole dictionary definition.

      Programming can often be seen as a form of compression. You don't want to write programs using an infinite bunch of IF THEN statements ;). But you don't want to pack everything too tightly if you think you might need to change some bits later on.

      --
    21. Re:13 years? by julesh · · Score: 1

      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.

      The word "iteration" is normally interpreted in this context to mean "a small chunk of an ongoing development process that ends with a public release". The first iteration of C++ development ended when Stroustrup first released Cfront to the public, some time around 1983.

    22. Re:13 years? by blair1q · · Score: 1

      And 11 years for the second iteration is agile development.

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

      ModParentUpEx64!

      --
      I am TheRaven on Soylent News
    24. 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
    25. Re:13 years? by TheRaven64 · · Score: 1

      Yes, but I thought I could get away without explaining it...

      --
      I am TheRaven on Soylent News
    26. Re:13 years? by introp · · Score: 1

      While it'll be nice to get native lambdas, the above example is a bit contrived; it's a lot prettier than this in current C++. With boost's lambda:

      vector<int> foo(5, 0);

      // one example
      int n = 42;
      for_each(foo.begin(), foo.end(), _1 = var(n)++);

      // and another
      for_each(foo.begin(), foo.end(), cout << _1 << '\n');

      The syntax isn't perfect, but can be very handy for throwing together prototypes, descriptive code, etc.

    27. Re:13 years? by Anonymous Coward · · Score: 0

      Previous C++ standard came out in 2003.

    28. Re:13 years? by m50d · · Score: 1

      I presume he's talking about functors - you can overload the "() operator" in C++ (the same way you overload any other operator), so you can create classes that act as functions. They can be used without modifying existing code, so they're more useful than the myriad java Function interfaces, but they still require masses of typing.

      --
      I am trolling
    29. Re:13 years? by shutdown+-p+now · · Score: 1

      Lambdas (anonymous functions with potential captured state) in most imperative languages are essentially sugar for objects. That's what they are pretty much by definition.

    30. Re:13 years? by shutdown+-p+now · · Score: 1

      The previous standard is actually C++03, though the changes from C++98 were mostly minor.

    31. Re:13 years? by shutdown+-p+now · · Score: 1

      C++ didn't exist as a standardized language till 13 years ago.

      It did, it just wasn't an ISO standard. This book was a defacto standard until ISO, though.

    32. Re:13 years? by superwiz · · Score: 1

      Not really. Maybe in compilers which ignored the standard. But the best you can do is operator()() in anonymous structures. However the standard does not allow them.

      --
      Any guest worker system is indistinguishable from indentured servitude.
    33. Re:13 years? by superwiz · · Score: 1

      No, no. This is C++. Parsing!

      --
      Any guest worker system is indistinguishable from indentured servitude.
    34. Re:13 years? by gknoy · · Score: 1

      You can, but his explanation made it funnier for those of us who didn't have that windows API background. :)

    35. Re:13 years? by OeLeWaPpErKe · · Score: 1

      Except the C++ version of this does support many things that functional languages do. Currying for example (binding only part of the arguments of a function). In C++ you can do this :

      int substract(int a, int b) { return a - b; }

      substract(2,1); // 1
      auto f = bind(substract, _2, _1);
      f(2,1); // -1

      auto f2 = bind(substract, _1, 3);
      f2(4); // 1

      auto f3 = bind(substract, _1, _1);
      f3(1); // 0, obviously gives 0 for all inputs

      You have to admit, pretty functional, no ? But it doesn't stop at currying. And you get all this with *zero* runtime overhead (as long as you stay away from "virtual"). The final program does not execute anything it doesn't actually have to, it doesn't dereference pointers, it doesn't do weird string lookups, it doesn't ... In general you tell it to substract 2 numbers, and it substracts 2 numbers. Nothing more, nothing less.

    36. Re:13 years? by EnsilZah · · Score: 1

      It said 13 years since the first iteration.
      Obviously there was a zeroth iteration before that.

    37. Re:13 years? by TheTyrannyOfForcedRe · · Score: 1

      Lambdas (anonymous functions with potential captured state) in most imperative languages are essentially sugar for objects. That's what they are pretty much by definition.

      The thing with captured state is called a "closure."

      --
      "Liechtenstein is the world's largest producer of sausage casings, potassium storage units, and false teeth."
    38. Re:13 years? by shutdown+-p+now · · Score: 1

      The resulting object is a closure. The syntactic construct that produces such an object at runtime is a lambda.

    39. Re:13 years? by Anonymous Coward · · Score: 0

      Yes, lambdas and closures allow creation of entities with object-like attributes. The difference is that the attributes in use are fine-grained. I think there are, oh say, 15 attributes of an object in a full object-oriented language. Proper lambdas and closures (they are separate, orthogonal concepts) allow one to choose a desired subset of the 15 attributes. One needn't always use either nothing or full-blown objects. Choose the functionality that is needed, from flyweight to heavyweight, in a continuum rather than as a step function.

    40. Re:13 years? by Anonymous Coward · · Score: 0

      That's the same as Java, except they called them anonymous inner classes.

    41. Re:13 years? by rgviza · · Score: 1

      I think what he means is microsoft poorly documented the api, as well as changed the api constantly and there was severe lag updating documentation. So the win api was always changing, the documentation was never right and trying to write a compiler for windows was a little like trying to climb into a car that was moving at 90mph and zig zagging randomly.

      --
      Don't kid yourself. It's the size of the regexp AND how you use it that counts.
  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. Still playing catch-up to C#. by Anonymous Coward · · Score: 0, Troll

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

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

      Yeah but this one goes to eleven!

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

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

    4. Re:Still playing catch-up to C#. by siride · · Score: 0

      What's the patent FUD, specifically? I'm not talking about some obscure part of the Winforms API, I mean in the core language itself.

      And you forget that C++ has a giant environment to install as well, but due to age, that is generally part of the OS as is. In time, modern generation languages will end up in the same category. 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.

    5. Re:Still playing catch-up to C#. by Waffle+Iron · · Score: 1

      What's the patent FUD, specifically? I'm not talking about some obscure part of the Winforms API, I mean in the core language itself.

      Any core language is almost useless without its standard and/or de facto libraries. Microsoft's patent policies on the libraries associated with C# (not just Winforms) are intentionally vague and confusing. Nobody really knows what conditions the patents may be used under, and by whom. This passive-aggressive stance on patents is a standard Microsoft strategy, and it's been pretty effective in general.

      And you forget that C++ has a giant environment to install as well, but due to age, that is generally part of the OS as is.

      Doesn't matter to the average user. If they have to worry about downloading and maintaining a huge pile of optional software libraries to run a sudoku puzzle, that's a hassle.

      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.

      Hence the need to choose a monkey name for your 2nd-class-citizen project for non-Windows platforms.

    6. Re:Still playing catch-up to C#. by Anonymous Coward · · Score: 1

      C++ has a giant environment to install as well

      No, it doesn't.

    7. Re:Still playing catch-up to C#. by lgw · · Score: 1

      Pretty much everything new in C++ 0x was around in the Boost libraries before showing up in C#. (A lot of the Boost stuff is written by C++ committee members). Standards usually follow years behind use. (The SCSI standard is my favorite for that- you know a particular SCSI rev is obsolete when the standard finally gets ratified).

      These day you don't even need Boost: most of the stuff in the standard is already available in most compilers, if you set the right switches. Heck, even Visual Studio has a lot of it.

      --
      Socialism: a lie told by totalitarians and believed by fools.
    8. Re:Still playing catch-up to C#. by koreaman · · Score: 1

      You're worried about hassle for the "average user" who runs Sudoku apps. These users are on Windows. For tthose who are on Mac, Macs have a good enough package installation system that it's not too big of a deal for packages to have prerequisites.

      BBut anyway,why are you citing external factors to somehow prove that C# iis an inferior language? Its "goodness" is in no way diminished by the fact that few platforms have implementations written for them.

    9. Re:Still playing catch-up to C#. by Waffle+Iron · · Score: 1

      BBut anyway,why are you citing external factors to somehow prove that C# iis an inferior language? Its "goodness" is in no way diminished by the fact that few platforms have implementations written for them.

      Intrinsic "goodness" is not the only relevant factor unless you operate in an ivory tower situation. For the real world, you have to take into account all of the aspects associated with using any given language. This includes deployment, developer availability, licensing, performance, suitability for the particular problem to be solved, etc.

    10. Re:Still playing catch-up to C#. by siride · · Score: 0

      Did you bother reading the rest of my comment?

    11. 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!

    12. Re:Still playing catch-up to C#. by ianare · · Score: 1

      I wholeheartedly agree with your points, but would have to hand in my geek card if I didn't correct you on at least one point : "mono" means "monkey" in Spanish (Icaza, its creator, is Mexican), it is not a species of monkey.

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

      It's /. after all :/

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

    15. Re:Still playing catch-up to C#. by Meneth · · Score: 1

      Now we just have to wait for compilers to start adopting the new spec...

      GCC supports most of the specs already.

    16. Re:Still playing catch-up to C#. by the_greywolf · · Score: 1

      They already do, to varying degrees: Apache has a wiki entry describing levels of support.

      --
      grey wolf
      LET FORTRAN DIE!
    17. Re:Still playing catch-up to C#. by the_greywolf · · Score: 1

      What's the patent FUD, specifically? I'm not talking about some obscure part of the Winforms API, I mean in the core language itself.

      Microsoft made some veiled threats a few years ago, intimating that their deal with Novell for Mono was exclusive. No one is really privy to the terms of that arrangement, but it made a lot of people really nervous.

      And you forget that C++ has a giant environment to install as well, but due to age, that is generally part of the OS as is.

      C++ is quite capable of operating entirely without a run-time environment. It depends only on the C++ standard library and the C standard library, which, while implemented by the OS, are completely optional.

      In time, modern generation languages will end up in the same category. 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.

      But this is not the case on non-Windows platforms.

      --
      grey wolf
      LET FORTRAN DIE!
    18. Re:Still playing catch-up to C#. by NoNonAlphaCharsHere · · Score: 1

      Unfortunately, in both C# and C++, eleven is an invalid value, but there was no exception handler, so...

    19. Re:Still playing catch-up to C#. by Anonymous Coward · · Score: 0

      "Goodness" is a legitimate word, but most native English speakers would say "quality" here.

    20. Re:Still playing catch-up to C#. by shutdown+-p+now · · Score: 1

      The comparison still doesn't make sense, because C++ and C# are languages on different levels of abstractions. You use C++ when you want to be close to the metal (and think that C is too simplified and requires too much hand holding for everything). You use C# when you're okay with a memory-safe, garbage-collected environment.

      This is quite evident in feature design, too. For example, C# lambdas always automatically capture any variables from the outside scope that they use, and the lifetime of those variables is magically extended - this is possible because GC takes care of it. In C++0x, lambdas capture things explicitly (you can auto-capture everything used in the body, but that is also an explicit choice; default is "no capture"), and if you capture by reference, there's no lifetime extension for captured variables - if you need that, you have to manually use shared_ptr (or something similar).

      Now we just have to wait for compilers to start adopting the new spec...

      They already are. E.g. lambdas can be used in Visual C++ 2010 (released over a year now), and in g++ since 4.5. Similarly, auto, nullptr, rvalue references and static_assert are all available in current stable releases of both compilers. Most of the library is also there, so start using std::unique_ptr and std::shared_ptr today (and forget about TR1).

    21. Re:Still playing catch-up to C#. by koreaman · · Score: 1

      I'm a native English speaker who had just woken up when I wrote that :)

    22. Re:Still playing catch-up to C#. by zeroduck · · Score: 1

      I don't use Windows anywhere but at work, so I'm pretty clueless about the situation. My work laptop has Windows 7 on it and I've had to download (myself) .Net Framework 1.1 and 4.0 for different things I run (Parker ACRView and Microsoft Expression Encoder). I don't know if those are included by default, and our IT guys just leave it out for some reason.

    23. Re:Still playing catch-up to C#. by TBBle · · Score: 1

      Nor have C++ developers chosen a monkey species after which to name its 2nd-class-citizen cross-platform implementation.

      Monkey? I always assumed it was named after the disease teenagers get from kissing too promiscuously...

      --
      Paul "TBBle" Hampson
      Paul.Hampson@Pobox.Com
  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 daid303 · · Score: 1, Insightful

      If you are putting binary flags in enums then you are using them wrong. And that's why you are no longer allowed to do so. It's a GOOD thing.

      You want bitfields: http://msdn.microsoft.com/en-us/library/ewwyfdbe(v=vs.71).aspx

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

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

    4. Re:Nice but... by Anonymous Coward · · Score: 1

      Enums have always been one of the best ways to declare bit combinations, given the weak typing of C and C++ in general. Bitfields, OTOH, are mostly useless. Driver writers don't use them, nor do kernel writers: that shit is unpredictable. And userspace/applications has little use for them in the first place.

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

    6. Re:Nice but... by Anonymous Coward · · Score: 0

      I've asked a bunch of times and never received an answer, so can you please explain the ludditic tendencies of your type? Why do you wish progress froze? Is it because you feel yourself becoming less relevant?

    7. Re:Nice but... by larry+bagina · · Score: 1

      gcc and clang will optimize multiple bit field sets into one or two and/or operations.

      --
      Do you even lift?

      These aren't the 'roids you're looking for.

    8. Re:Nice but... by e70838 · · Score: 1

      It is the most used way, not the best one. It is an inappropriate way. Even if bitfields have drawbacks, simple constants defined in a namespace remain a better choice.

    9. Re:Nice but... by Arlet · · Score: 1

      Not if the bitfields are volatile, which is common for hardware registers.

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

    11. Re:Nice but... by Anonymous Coward · · Score: 1

      I can't imagine that there are many people who know much about Lambda functions and give them a 'meh'. If all you know about them is what is in that article, then fair enough, because its a terrible example, but otherwise it just makes you sound like a luddite. I'd be interested in hearing your opinion about why they are just a 'meh' feature though...

    12. Re:Nice but... by Anonymous Coward · · Score: 0

      Bit fields are inappropriate for hardware registers anyway, because the layout of the bits is implementation defined.

    13. 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
    14. Re:Nice but... by JohnnyBGod · · Score: 3, Interesting

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

    15. Re:Nice but... by Anonymous Coward · · Score: 0

      Yes, let's switch to platform specific code. Just shoot yourself.

    16. Re:Nice but... by rjstanford · · Score: 1

      Agreed. Low level language features exist for a reason, but their use (outside of a few specialized fields where bit-level optimization is preferred to code-readability-and-use optimization) is limited. Making it slightly less convenient (ie: use an int like we always have) for a (relative) few, while encouraging the many to use the more comprehensible variant, is not a bad idea.

      --
      You're special forces then? That's great! I just love your olympics!
    17. Re:Nice but... by Anonymous Coward · · Score: 0

      Just use: class myenum { public: enum blabla { ... } };

      a class is also a namespace.

    18. Re:Nice but... by Nova77 · · Score: 1

      Even better

      for (auto &x: collection)

    19. Re:Nice but... by fnj · · Score: 1

      You're right, that is very cool.

    20. Re:Nice but... by Dcnjoe60 · · Score: 1

      It is the most used way, not the best one. It is an inappropriate way. Even if bitfields have drawbacks, simple constants defined in a namespace remain a better choice.

      It depends on what you mean by the word "best." There must be some reason that doing it this way is the most used way. Evidently, for many, it seems that it is the "best" way to do it. Since "best" is such an ambiguous word, maybe it would be better to elaborate on why it is inferior? Does it use more memory? Is it slower to execute? Is it more difficult to maintain? Depending on one's needs, the answer to any of those questions might influence what "best" means.

    21. Re:Nice but... by Anonymous Coward · · Score: 0

      Since they killed enums for me then I'll just go back to #define s. I win.

    22. Re:Nice but... by ConceptJunkie · · Score: 1

      they decided to make the name Y2K compliant this time

      Yes, because a lot of people might be confused, thinking the standard came out in 1911. ;-)

      Regarding the type inference, I always found that to be a glaring deficiency in STL. I always thought Borland's style of implementation was much better to use, although I can understand it wasn't as flexible or fast as templates. I did the same thing in my own class library back before I used templates (and they were standard), so I could do for-loops like this:

      for (iterator i(collection); i.hasMore( ); i++) {
              something = collection[i]...

      The new use for "auto" solves this whole issue very neatly.

      --
      You are in a maze of twisty little passages, all alike.
    23. Re:Nice but... by Anonymous Coward · · Score: 0

      You mean a union?

      Also, you use the words "bits" and "fields" to describe how a bitfield is less flexible... than itself?

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

    25. Re:Nice but... by geekoid · · Score: 1

      "There must be some reason that doing it this way is the most used way. "

      Probably laziness. The fact that a lot of people sue it does not make it good: see: Access.
      Best as in: It's poor engineering to use them. If you don't understand that, please stick to VB.

      --
      The Kruger Dunning explains most post on /. http://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect
    26. Re:Nice but... by gerddie · · Score: 1

      As a long time C++ guy (Borland C++ days), I look at some of these features and think "so what?" (Lambda functions, please.) [...] 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.

      When you use iterators, then you probably use algorithms like transform or for_each. for these, lambdas are a perfect supplement.

    27. Re:Nice but... by Carewolf · · Score: 0

      It consumes memory, use #define or enum instead, or wait for C++ to standardize compile-time or interface constants.

    28. Re:Nice but... by marcosdumay · · Score: 1

      Please, "const" is available for a long time now.

    29. Re:Nice but... by Palshife · · Score: 1

      Yeah, just a little known compiler called GCC.

      --
      Attention deficit disorder is a complicated issue, spanning several major... HEY LET'S GO RIDE BIKES!
    30. Re:Nice but... by Carewolf · · Score: 1

      Let me correct that immediately, I think my choice of words confused the problem. The problem is not that it 'consumes' memory, the problem is that it _is_ in memory. This triggers memory-aliasing and means the constant is not truly constant, and the compiler can not optimize any expressions using such a constant. Any expression using such a constant _has_ to load the constant from memory in case the constant was changed.

    31. Re:Nice but... by BeanThere · · Score: 1

      Yes, sure, but this type of nanny-state-ism in a compiler clearly goes against the traditional historical spirit of C++ as being the best assembly language out there ..

    32. Re:Nice but... by Carewolf · · Score: 0

      Qt:

      foreach(QObject *qo, qlist) {
          awesomeStuff(qo);
      }

    33. 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++.

    34. Re:Nice but... by Anonymous Coward · · Score: 0

      Which part of "const" don't you understand? The better way is to add "static" too, that way it will be completely optimized out:

      static const int SOME_BINARY_FLAG = 0xff00ff;

    35. Re:Nice but... by Carewolf · · Score: 1

      Which part of "const" don't you understand?

      I understand all if it. I don't think you understand how const is defined in C++. Static here btw, just means the value is not exported (or if in a class, exported as a class member).


      static const int SOME_BINARY_FLAG = 0xff00ff;

      void main() {
            const int *a = &SOME_BINARY_FLAG;
            int *b = const_cast<int*>(a);
            *b = 0xdead; // oops!
      }

      And that is just the polite 'clean' way of doing it..

    36. 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;
      }

    37. Re:Nice but... by Just+Some+Guy · · Score: 1

      At that point, what's the advantage over a #define? I do some C, but not enough to appreciate that level of subtlety.

      --
      Dewey, what part of this looks like authorities should be involved?
    38. 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.

    39. Re:Nice but... by Mr+Z · · Score: 1

      Not all compilers will optimize that out. The embedded compiler I use still outputs an initializer record for that. Marking it 'static' means I actually get a copy of the initializer record in every compilation unit that includes the constant, which is even "better".

    40. Re:Nice but... by Duhavid · · Score: 1

      I will have a stab at answering.

      For me, the new language features should be added, but their usage should correlate to being able to solve a problem better or faster, or more completely, or something like that. I see too many developers focus on "new" for the sake of "new" only. I don't see the OP as being ludditic, but focused on "how does this new thing actually improve things". Many new features in a given language are either not useful in a given scenario, or would cause the developer to have to take something that works and re-implement it, with the attendant question of "how is this making my application better".

      --
      emt 377 emt 4
    41. Re:Nice but... by yuriks · · Score: 1

      But modifying a const variable by casting the const away is undefined behaviour and has always been. Your code example is illegal, the memory SOME_BINARY_FLAG is in may not even be modifiable (it may be in ROM, for example.)

      And static means that the compiler knows this symbol is only used in this TU, and that if you don't take it's address, it doesn't need to emit it as a variable in memory.

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

    43. Re:Nice but... by ProzacPatient · · Score: 1

      Everybody has their own tastes but for those coming from an MSVC background but are itching to try out new features I highly recommend CodeLite: http://www.codelite.org/

    44. 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
    45. Re:Nice but... by Anonymous Coward · · Score: 0

      ATT compilers were the only way to get current features during the early 90's when, seemingly every few weeks, new features were being added to C++ , along with a new compiler version from ATT. Not sure if same situation today.

      GCC wasn't bad either... supported-ish templates well before any of the commercial compilers I was using, at the time, besides the ATT ones.

      Above was mostly hosted on sunos, and a little on linux, and solaris (IIRC around 1993).

      M$ advertised that their stuff (visual c++ hosted on winnt 3.1) worked with templates, etc. back then, but it didn't, and a call to support would confirm, it was just marketing lies. This probably hasn't changed with these new features. If stuck on M$, you will likely have to wait a while for tools to catch up, and take anything that comes out of their marketing droids mouths with a huge grain of salt before wasting your money.

    46. Re:Nice but... by shutdown+-p+now · · Score: 1

      Also I totally don't understand why enum class no longer casts to ints... it totally makes using binary flags impossible

      You can still cast scoped enums to int, you just have to do so explicitly (much like C#). This is so that a wrong overload does not occasionally gets called.

      As for binary flags, just overload operator& and operator| for your enums if you don't want the users of enum to have to write casts.

    47. Re:Nice but... by shutdown+-p+now · · Score: 1

      I look at some of these features and think "so what?" (Lambda functions, please.)

      Lambda functions enable the use of strongly typed generic algorithms (filter/map/fold/...), instead of writing them manually in terms of loops and conditions every time you want one.

    48. Re:Nice but... by shutdown+-p+now · · Score: 1

      Better yet, use "const auto&" unless you intend to mutate elements within the loop.

    49. Re:Nice but... by alexo · · Score: 1

      static const variables that never have their address taken don't have to reside in memory.

    50. Re:Nice but... by superwiz · · Score: 1

      Hear, Hear! It's responsible for at least 10%-20% of all the written C++ code. You generally have the option of either writing out a header of a for loop on 3 lines or doing 2 typedefs (still 3 lines in total).

      --
      Any guest worker system is indistinguishable from indentured servitude.
    51. Re:Nice but... by Savantissimo · · Score: 0

      Don't you get it? With the new standard, now C++, the popular automatic bug generator that has eaten more minds than Yog-Sothoth, can generate faster, bigger, more advanced and totally incomprehensible bugs!
      I swear, people like you, it's almost like you want your code to actually work instead of make work.

      --
      "Is life so dear, or peace so sweet, as to be purchased at the price of chains and slavery?" - Patrick Henry
    52. Re:Nice but... by Dcnjoe60 · · Score: 1

      "There must be some reason that doing it this way is the most used way. "

      Probably laziness. The fact that a lot of people sue it does not make it good: see: Access.
      Best as in: It's poor engineering to use them. If you don't understand that, please stick to VB.

      For those people choosing to use access, based on their selection criteria, it must be "best" or they wouldn't have chosen it. With regards to VB. It was best, or one of them, for things like quick and dirty prototyping and testing concepts. However, the original post is not about access or vb but instead C++. So, assuming we have real programmers, if the majority of them have chosen to code in a certain style or to implement an algorihm in a certain way, there must be a good reason for it other than laziness (in which case, they probably wouldn't be using C++ in the first place).

      Even using "engineering" as a definition for best is problematic. Good engineering in academia is not the same thing in the real world. There is a real difference between what conceptually is the "best" engineering and what is practical with regards to the environment an application will run it.

      But even if engineering is to be the basis for "best," what is good engineering to be based on? Is it portability? Is it maintainability? Is it execution speed or memory footprint?

      Back in my university days, we were challenged to write a COBOL application that would calculate the trajectory of a space craft to the moon and back (this was during the Apollo missions). Obviously, nobody in their right mind would do that in a real world program, although it did require a lot of good "engineering." So, does that mean the COBOL program was the best because the engineering required far exceeded that needed to do it in Fortran? BTW, the point of the programming exercise was to show that just about any language could be used to code any type of program.

      I think that most "best practices" are based on what most programmers are doing with the language in question. As such, if most C++ programmers are using enums in a certain way, it kind of becomes the best practice, until enough programmers change to doing it a different way. Most organizations I have worked for/with pretty standard coding practices, which they have determined to be their best way of implementing things (right or wrong).

    53. Re:Nice but... by Roachie · · Score: 1

      Thanks, I work out a lot!

      --
      This sig is not paradoxical or ironic.
    54. Re:Nice but... by David+Greene · · Score: 1

      For me, the new language features should be added, but their usage should correlate to being able to solve a problem better or faster, or more completely, or something like that.

      The C++ committee agrees with you. The sentiment is correct. I would like the GP to explain which new features he/she thinks are unnecessary. Otherwise it is just ranting.

      --

    55. Re:Nice but... by Carewolf · · Score: 1

      Thanks, I thought I had heard talk of making this more accessible. Amazingly how many people are objecting to the fact that it is necessary.

      Does constexp also force (or compiler-time assert) all right-hand expressions to be constexpr?

    56. Re:Nice but... by Carewolf · · Score: 1

      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.

      Speaking as someone who works on a C++ compiler, you are entirely wrong about me being entirely wrong ;)
      Then again we might both be right or wrong depending on what is defined or undefined behaviour. Const-cast is a standard cast, I admit I haven't checked in the spec and never worked on that part, but I would be surprised if a well-defined part of C++ would cause undefined behaviour when used for its intended purpose.

    57. Re:Nice but... by Suiggy · · Score: 1

      Yes. They must be compile time and they must not induce side-effects.

    58. Re:Nice but... by Anonymous Coward · · Score: 0

      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.

      They do cast to ints still, just not implicitly.

    59. Re:Nice but... by criminy · · Score: 1

      Concepts were supposed to fix this problem, but they were booted out at the last minute.

      I'm enjoying the implication that, when it comes to standardization, "at the last minute" can mean "two years earlier".

    60. Re:Nice but... by TheRaven64 · · Score: 1

      Const cast is irrelevant, we're talking about a const declaration. A const cast is entirely different. In fact, const means 6 unrelated things in C++, depending on where you write it, which is one of the many reasons why I detest the language.

      When a global / static variable is declared const, then that means that it can never be assigned to after initialization. You then have two cases. For types with a trivial constructor, this means that it will be in the immutable data section of the executable and will be initialized in the binary. For types without a trivial constructor, space is allocated in the global data section, and the constructor is called by the linker (or, optionally, lazily for scoped statics).

      An integer has a trivial constructor, so the compiler can guarantee its run time value. If your compiler is not doing constant propagation on such values, then it is even worse than GCC, which is quite impressive.

      Even if you ignore all of the C++ front end, by the time this gets to the language-agnostic optimizers, the integer will be in a section of the IR that is marked as initialized and immutable. A trivial constant propagation pass will replace every load of this value with the result and decrement its use count. Once its use count reaches zero, dead code elimination will remove it.

      --
      I am TheRaven on Soylent News
    61. Re:Nice but... by oobayly · · Score: 1

      I was going to quote Verity Stob's Variables Won't Constants Aren't, but while it compiled using g77 it didn't work as planned. Probably a good thing too. It does work with gcc though.


      #include

      using namespace std;

      int main(int argv, char** argc) {
              const int i = 12345;
              cout << "i = " << i << "\n";

              *(int*)(int)&i = 43;
              cout << "i = " << i << "\n";

              return 0;
      }

    62. Re:Nice but... by marcosdumay · · Score: 1

      In gcc (Debian 4.4.5-8):

      Error: cast from 'const int*' to 'int' loses precision

      Not at all what I was expecting. It didn't refuse to lose constness (I was expecting that), didn't complain about the & operator aplied to a const (that would be the right behaviour), and didn't work! Amazing. Pedantic and Wall changes nothing, changing i to 'const short' also changes nothing.

      That said, that is a problem of the compilers. The standard says the & operator can't apply to a const.

    63. Re:Nice but... by Carewolf · · Score: 1

      Interesting. I read the same from some of the other comments and realised I might be wrong. Funny, I usually bash people when they refer to 'static' without qualifying which 'static' definition, but I forgot 'const' is also somewhat different depending on context.

      I can defend my point for most other uses of 'const', but the truth is; this was about global 'const', and I was wrong. Thank you. ;)

    64. Re:Nice but... by TheRaven64 · · Score: 1

      This is the main reason why I detest C++. In any sane language, you learn something and its true in any context. In C++, you learn something and it doesn't hold even for an almost identical line somewhere else in the program.

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

    1. Re:Cruft removed? by Anonymous Coward · · Score: 0

      The old meaning of the auto keyword has been removed, no one ever used it. There are others but this is the first that comes to mind as the keyword is reused for a new feature.

    2. Re:Cruft removed? by pauljlucas · · Score: 1

      Have they *removed* anything at all from it?

      They can't because it would break people's code and most people get upset when that happens.

      In a Google Talk about the Go language, Rob Pike make a snide remark about how they made the recent iteration of Go smaller unlike some other languages. The only reason they can get away with that is because there's very little Go code out there.

      In contrast, there's tons of C++ and Java code out there. Both languages have cruft that I'd like to see removed too, but it simply can't be done. That's the price of success.

      --
      If you reply, do so only to what I explicitly wrote. If I didn't write it, don't assume or infer it.
    3. Re:Cruft removed? by Anonymous Coward · · Score: 1

      If you don't want the whole language, don't use it all. Draw up a list of crufty things that you think ought to be removed from C++ and don't use them. There's no reason to break other people's code that relied on the standard because you don't want to use those features. It's not as though it's mandatory to use every language feature in every project, even where it's not appropriate (although many coders, ahem, don't seem to grok this).

      I do this for all my C++ projects. All of them forbid the use of multiple inheritance, metaprogramming, non-trivial template usage, RTTI. Some forbid C++ exceptions. Just pick and chose what you want.

      Captcha: perplex -- which is what the above comment did to me.

    4. Re:Cruft removed? by Anonymous Coward · · Score: 0

      Both languages have cruft that I'd like to see removed too, but it simply can't be done. That's the price of success.

      Well now that's just untrue. You *can* remove cruft from a language - you just have to do it the right way. Particularly, doing it through a couple releases and deprecating (AKA, warning people "this is going to be removed") features and then removing the feature totally in the subsequent releases. It really isn't that difficult to do...

    5. Re:Cruft removed? by kikito · · Score: 1

      Adding new features makes the code non-backwards compatible. Removing them does the same thing.

      I've seen it happen in other languages (ruby, for example) and it wasn't the end of the world. If you really, really need to keep compiling old code, you just use an older compiler.

    6. Re:Cruft removed? by kikito · · Score: 1

      I can do that if I program on isolation, without using others' work, and without external libs.

      That's precisely the opposite of my way of working.

    7. Re:Cruft removed? by Anonymous Coward · · Score: 0

      Well, they could, you know, just declare that stuff deprecated. That's what Java does anyhow. And that's what the C++ guys are going with (they are deprecating stuff like auto_ptr, exception specifications, and export templates). They just aren't going far enough.

      Notice you can still freely use those features. It just means you will get warnings, and their documentation will be relegated to the appendices of books.

    8. Re:Cruft removed? by Anonymous Coward · · Score: 1

      Well, if you aren't in charge of the projects then you have to accept others' coding conventions and choice of language features (and design decisions, development process, meeting timezone, etc). The point is that C++ doesn't force anyone to use those features -- as I commented above, nearly all of my C++ projects use a strictly-defined subset of C++ that is properly tailored to the task at hand. If you work on a project with others, it's not the language forcing you to use those features, they are.

      In terms of libraries, you can usually wrap them to your liking with a fairly thin abstraction layer that removes things you don't like. I routinely wrap libaries that throw exceptions (ugh) into exception-safe versions with my own error handling. This is the same as the previous graph -- if you don't like the interface, don't blame the language for including those features, blame the authorfor not doing it your way.

      The language "cruft" isn't forcing anyone to use those features. You can already use a language that you call C++kikito, a strict subset of C++, wherever you want. You can even try to convince others to use C++K, although you shouldn't be surprised if projects that started on C++98 aren't keen to convert to C++K. That language exists and there's no reason to remove features from C++98 or C++11 just to satisfy your desire that everyone use C++K.

    9. Re:Cruft removed? by cratermoon · · Score: 1

      Did you read the article though? The new standard completely changes the meaning of the auto keyword. That alone will break code, and it's adding something. Come to think of it, though, the article doesn't mention what, if anything, will replace the behavior that's going away.

    10. Re:Cruft removed? by pauljlucas · · Score: 1

      The new standard completely changes the meaning of the auto keyword. That alone will break code, and it's adding something. Come to think of it, though, the article doesn't mention what, if anything, will replace the behavior that's going away.

      Do you actually code in C++? Nobody uses the auto keyword in its original meaning. Its original use was completely redundant and was never needed, not even for C. Hence, nothing needs to replace the original auto.

      --
      If you reply, do so only to what I explicitly wrote. If I didn't write it, don't assume or infer it.
    11. Re:Cruft removed? by the_greywolf · · Score: 1

      auto is the default behavior of newly-declared objects. It simply means "automatic storage duration."

      No one actually ever used it, so it was decided that it wouldn't be missed. The new meaning ("automatic type") is clearer and more useful, IMO.

      --
      grey wolf
      LET FORTRAN DIE!
    12. Re:Cruft removed? by shutdown+-p+now · · Score: 1

      Particularly, doing it through a couple releases and deprecating (AKA, warning people "this is going to be removed") features and then removing the feature totally in the subsequent releases.

      In this case, we're talking an average of 5 years between releases, and there have only been two so far (and only one of them was major).

      The active policy, in fact, is that a feature must be deprecated for one release before it can be removed. Hence e.g. auto_ptr won't be ditched until C++1x.

    13. Re:Cruft removed? by sc0p3 · · Score: 1

      See C#. All the good bits, with all the cruft skimmed off.

  6. Looks cool... by jellomizer · · Score: 1

    I am glad that C++ is still evolving. That last major improvement I remember was the addition of the string class. Then shortly after that my professional focus moved away from C and C++ and towards higher level languages (.NET, PHP, Python, Java, etc...). I just recently started my own personal project so I decided to relearn C++ again, and I noticed there is a fair amount of new stuff that wasn't there before (or I was never taught)

    --
    If something is so important that you feel the need to post it on the internet... It probably isn't that important.
    1. Re:Looks cool... by Anonymous Coward · · Score: 0

      I can't believe the article didn't mention variadic templates. They make it possible to do things like:

      struct A { A(int, char*); };
      std::vector<A> vec;
      vec.emplace_back(1, "test");

      instead of:

      struct A { A(int, char*); };
      std::vector<A> vec;
      vec.push_back(A(1, "test"));

      Before C++0x, adding something to this vector would have meant three constructor calls (default, custom, copy), a destructor call and allocating a temporary object. Using variadic templates you can forward the constructor call meaning only the custom constructor is called and that's it, no additional objects or calls. So now you have the efficiency of low-level C-like code with the convenience of not having to write any boilerplate code; the compiler takes care of all of that for you.

    2. Re:Looks cool... by e70838 · · Score: 1

      A new layer of syntactic hacks so that the language allows to do normal things with a reasonable efficiency.
      I am really impatient to try this new language, but previous experience suggests I will have to wait at least 3 years before seeing a standard compliant compiler.

    3. 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
    4. Re:Looks cool... by e70838 · · Score: 1

      Excellent link that shows that almost a third of features are not implemented. We all know that the last 10% of the features are the one that take the longer.
      More seriously, the features that I would really like to tinker with are concurrency and garbage collector. These features are far from implemented.

    5. Re:Looks cool... by Jonner · · Score: 1

      I am glad that C++ is still evolving. That last major improvement I remember was the addition of the string class. Then shortly after that my professional focus moved away from C and C++ and towards higher level languages (.NET, PHP, Python, Java, etc...). I just recently started my own personal project so I decided to relearn C++ again, and I noticed there is a fair amount of new stuff that wasn't there before (or I was never taught)

      While all of the new features sound like a step in the right direction, I remain unimpressed because it still doesn't have automatic memory management (garbage collection) built-in. Of course, there are numerous libraries that add it, but in incompatible ways. Until it's a standard part of the language, I don't think it's a good choice for new general application development. If you have legacy C++ and/or C code you want to maintain and improve, the new features probably very nice.

  7. Oh Snap. by crow_t_robot · · Score: 1

    Lambda expressions!

  8. Re:Cool! Meanwhile... by ciderbrew · · Score: 0

    Well, you'll be on the losing side so I guess you have a reason to worry. Did you know they are talking about the PS4 coming out in a few years?

  9. So... by fitten · · Score: 1

    Looks like C# from a few years ago. Honestly, it's really good that they're moving C++ forward, it's been lacking these features when other languages have embraced them for some time. I see they still use a plethora of ugly ass underbars, though.

    1. Re:So... by glwtta · · Score: 1

      I like the underbars, always makes me feel "closer to the hardware" when I see a lot of them.

      There's not reason for all languages to look the same.

      --
      sic transit gloria mundi
    2. Re:So... by JasterBobaMereel · · Score: 1

      ..Different languages are different for a reason, they do different jobs ...

      C# is trying to be the universal very high level language that embraces all paradigms and can be used for everything ...
      C is still a low level language allowing to program low level

      C++ is stuck in the middle and so should cover the ground where you want to abstract away from the machine, but don't want a VM getting in the way, if it moves too far towards C# is will start to be ignored ...

      Both C# and C++ seem to be falling into the trap of Greenspun's Tenth Rule,

      --
      Puteulanus fenestra mortis
    3. Re:So... by fitten · · Score: 1

      It makes me feel like I'm still programming in the 1980s. It's old and ugly. It's not a required "look", it's just an ancient custom. The compiler works just fine without underbars in names.

    4. Re:So... by fnj · · Score: 1

      I don't think there is any danger of that. You can make a C++ program just as low level as one in C, if you want. You can still compile any C code with a C++ compiler in C++ mode with generally only very minor tweaks to the expressions, and none of the tweaks changing the binary code generated. You can use as much of the added C++ features as you want; anywhere from none of them to all of them. In an ideal world there would be no reason to use a straight C compiler any more. The ways real life departs from an ideal world is mostly that C++ compilers are not universally available in all environments; none of them are yet fully C++2011 compliant; and they tend to be VERY slow.

    5. Re:So... by tepples · · Score: 1

      C# is trying to be the universal very high level language that embraces all paradigms and can be used for everything

      ...except non-PC, non-Microsoft platforms. (For example, MonoTouch and Mono for Android are still priced prohibitively for hobbyists.)

    6. Re:So... by Arlet · · Score: 1

      You can still compile any C code with a C++ compiler in C++ mode

      Except when the C code uses C++ keywords. Words like new, this and delete are common enough that there are plenty of C programs using them.

      Another good reason to use a C compiler to compile C code is that the compiler is much simpler, and most likely has fewer bugs.

    7. Re:So... by glwtta · · Score: 1

      It's not a required "look", it's just an ancient custom.

      I never said it was required, it's just a different look, it's not better or worse than camel casing. Obviously it's not a style you prefer.

      Like I said, there's no reason for all languages to look the same.

      --
      sic transit gloria mundi
    8. Re:So... by david_thornley · · Score: 1

      Yet another good reason for a C compiler is if you use any of the C99 features, since C has diverged from being a near-subset of C++.

      --
      "When you have eliminated the unacceptable, whatever is left, however improbable, must be the truthiness" - Holmes
    9. Re:So... by Jonner · · Score: 1

      I like the underbars, always makes me feel "closer to the hardware" when I see a lot of them.

      There's not reason for all languages to look the same.

      There's also no logical connection between underscores and hardware. I write Python all the time with lots of them.

    10. Re:So... by shutdown+-p+now · · Score: 1

      You can't reasonable compare a high-level language with a design approach of "when in doubt, convenience wins over perf or memory use" (hence VM, VM etc) and a language that can go all the way down to bare metal with a design approach of "if you don't use it, you don't pay for it" and "be fast by default, safety be damned".

    11. Re:So... by CSMoran · · Score: 1

      There's also no logical connection between underscores and hardware. I write Python all the time with lots of them.

      There's no logical connection in Python. In C++ there is, sorta, as everything that begins with "__" is implementation-specific (and often more tied to the hardware). Perhaps that's what the OP meant.

      --
      Every end has half a stick.
  10. 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
    1. Re:But... by geekoid · · Score: 1

      No, not at all. There are just as many articles like this as there was 12 years ago... there's just a lot more of political crap, so the ration had changed.

      --
      The Kruger Dunning explains most post on /. http://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect
    2. Re:But... by Anonymous Coward · · Score: 0

      The best comment I have seen on Slashdot since a very long time.

    3. Re:But... by blair1q · · Score: 1

      Like the tech economy, nerd-level news has been meh for a long while.

      Coincidentally, since shortly after the introduction of the last rev of the C++ standard...

      How much is gold?

  11. Biggest Change? by hal2814 · · Score: 4, Funny

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

    1. Re:Biggest Change? by Anonymous Coward · · Score: 0

      A long ways back, I used to use Fortran-90 ---- you primitives. Get a real language whose version is an order of magnitude higher than C++

    2. Re:Biggest Change? by 0xABADC0DA · · Score: 1

      I still think ++C++ would be better... the problem with C++ was always that they put the C stuff off to one side.

    3. Re:Biggest Change? by sconeu · · Score: 1

      But then the language would be undefined! That's UB there, modifying a value twice without an intervening sequence point!

      --
      General Relativity: Space-time tells matter where to go; Matter tells space-time what shape to be.
    4. Re:Biggest Change? by Jonner · · Score: 1

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

      It's certainly bigger. I thought it was complex before, but now it's a behemoth.

    5. Re:Biggest Change? by CSMoran · · Score: 1

      But then again, sequence points were removed in the new standard :). Of course it's still UB.

      --
      Every end has half a stick.
  12. That's way too modern by Anonymous Coward · · Score: 0

    Let's see how long until Stallman posts a long text criticizing it all...

  13. C++0x by Anonymous Coward · · Score: 0

    And C++0x? ( http://developers.slashdot.org/story/11/03/26/1949225/ISO-C-Committee-Approves-C0x-Final-Draft )

    1. 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.
    2. Re:C++0x by queBurro · · Score: 0

      C++xy apparently would have been better?

      --
      sag
    3. 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!

    4. Re:C++0x by DanTheStone · · Score: 1

      No, in hex (0x) you really can go to 11.

    5. Re:C++0x by TheRaven64 · · Score: 1

      Nope, C++0x is C++ 2011. C++11 does not exist.

      --
      I am TheRaven on Soylent News
    6. Re:C++0x by queBurro · · Score: 0

      For $2000 I'll build you one that goes to twelve!

      --
      sag
    7. Re:C++0x by fnj · · Score: 1

      And it shows they should never again make assumptions on finish dates. They never did get it done during the decade they targeted or assumed.

    8. Re:C++0x by geminidomino · · Score: 1

      In hindsight (I posted the same thing), it occurs to me they can still claim to hit the target range if they go in hex...

      But then it should have been C++ 0x0x

    9. Re:C++0x by jeremyp · · Score: 1

      Yes and in fact, if the constant starts with a leading zero, they should have really got it done by the end of 2007.

      --
      All I want is a secure system where it's easy to do anything I want. Is that too much to ask ~~ Randall Munroe
    10. Re:C++0x by Anonymous Coward · · Score: 0

      No... C++5uxC0x

  14. 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 Ergodicity · · Score: 0

      Agreed. C and C++ seem to love the idea of figuring out what the programmer's intention by looking at punctuation marks. For example, why on earth there's no function keyword? Make it two keywords, one for declaration and the other for implementation. The result is that a misplaced comma or a missing semi-colon (for example at the end of a function declaration) completely throws off the compiler. And, as Errol says, it makes the code completely unreadable. The new Lambda syntax is a good example. Would it be that painful to add a lambda keyword?

    2. 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 /.
    3. Re:Alternative syntax by yarnosh · · Score: 2

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

    4. 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
    5. Re:Alternative syntax by Anonymous Coward · · Score: 0

      Ouch ! I would definitely not qualify VB as a legible language.

    6. Re:Alternative syntax by nedlohs · · Score: 1

      Congrats you just broke every C++ program that used "lambda" (or whatever keyword you chose) as a variable/class/whatever name.

      And yes, while it may seem minor to you and something that can be fixed with search-n-replace, that's something to be avoided at almost any cost.

    7. Re:Alternative syntax by Anonymous Coward · · Score: 0

      You mean notation like this?

      if ($a == 5):
              echo "a equals 5";
              echo "...";
      elseif ($a == 6):
              echo "a equals 6";
              echo "!!!";
      else:
              echo "a is neither 5 nor 6";
      endif;

      That's the first time I've ever heard anyone say something positive about that - are you a VB user by any chance?

    8. Re:Alternative syntax by BetterThanCaesar · · Score: 1

      Even worse, it's _Bool with one underscore and uppercase B. If you #include<stdbool.h> you get a #define bool _Bool which you can undefine if you really need the bool name for your own code.

      See: stdbool.h

      --
      "Stop failing the Turing test!" -- Dilbert
    9. Re:Alternative syntax by Anonymous Coward · · Score: 0

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

      I can't believe anyone finds PHP to be readable. If you put a bit of effort into it, I am sure you can learn to read a non-toy programming language.

    10. Re:Alternative syntax by Ergodicity · · Score: 0

      There are simple workarounds for that, from using _lambda instead or creating a compatibility mode for older code. And, btw, what about all the keywords that have been added along the years? Have we broken every program that uses "string" (a much more common word than lambda)?

    11. Re:Alternative syntax by geekoid · · Score: 1

      Anyone who used 'lambda' as a variable class of method should be drummed out of the business. Seriously.

      --
      The Kruger Dunning explains most post on /. http://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect
    12. Re:Alternative syntax by david_thornley · · Score: 1

      That's "std::string" to you, bud. Library names get put into a namespace like "std", but you can't do that with keywords.

      If your program uses "string" as an identifier, then don't have "using namespace std;" or "using std::string;" in your program, and refer to the C++ library string as "std::string" everywhere you use it. It's a little awkward, but you don't have to figure out which identifier is which. Using "lambda" or "function" as a keyword means these are interpreted as keywords by the parser, and that's independent of namespace.

      --
      "When you have eliminated the unacceptable, whatever is left, however improbable, must be the truthiness" - Holmes
    13. Re:Alternative syntax by marcosdumay · · Score: 1

      If you care to look you'll see that "string" isn't a keyword in C++.

    14. Re:Alternative syntax by Carewolf · · Score: 1

      Have we broken every program that uses "string" (a much more common word than lambda)?

      Nope, that is why we have namespaces and the real name is std::string.

    15. Re:Alternative syntax by Ergodicity · · Score: 0

      The article uses > void naiveswap(string &a, string & b) which made me believe (I guess erroneously) that "string" is now a keyword. Still, template, for_each and other keywords were added after the fact.

    16. Re:Alternative syntax by Just+Some+Guy · · Score: 1

      Somewhere, an APL hacker is giggling.

      --
      Dewey, what part of this looks like authorities should be involved?
    17. Re:Alternative syntax by Just+Some+Guy · · Score: 1

      If I ever opened a C++ file and saw std\string, I'd have to throatstab someone.

      --
      Dewey, what part of this looks like authorities should be involved?
    18. Re:Alternative syntax by david_thornley · · Score: 1

      B-but I started with alpha, beta, gamma, delta, ....

      --
      "When you have eliminated the unacceptable, whatever is left, however improbable, must be the truthiness" - Holmes
    19. Re:Alternative syntax by spongman · · Score: 1

      why? have you never named a variable 'alpha' or 'delta'? why are some greek letters better than others?

    20. Re:Alternative syntax by b4dc0d3r · · Score: 1

      Pretty funny, considering I never was "taught" C++, I learned to program by reading source code. Eventually I was able to tell good code from bad, and got better. At this point, documentation just slows me down and I dive into the code. C/C++/C#/JavaScript/Java/SQL/whatever.

      People need to consider this like any other field. If you can't understand what others in the field are writing, and especially if you don't read what others are writing, you need practice reading.

      *(Unless you're talking about PERL, which was designed to be write-only, written in ink on unseekable media. If the program doesn't work, start over I think is what Larry recommends)

    21. Re:Alternative syntax by nedlohs · · Score: 1

      Why?

      void functionname(FooBar &a, myClass &b)

      does that really make you believe that FooBar and myClass are keywords?

      for_each is also not a keyword.

      And yes, keywords have been added to C+11. But not lightly, and if something can be implemented without adding new keywords it'll be done without adding them.

    22. Re:Alternative syntax by shutdown+-p+now · · Score: 1

      C++ samples normally assume "using namespace std".

      for_each is not a keyword, it's a library function.

      template has been in C++ for several years before it became an ISO standard (it was already in ARM).

      The only new keyword that has been added in C++0x are static_assert, constexpr, decltype and nullptr. In all cases, when a new keyword is added, there is a thorough check of existing code to make sure that it breaks no-one or almost no-one (it is for that reason that "decltype" was used instead of "typeof" - the latter was the original proposal).

    23. Re:Alternative syntax by shutdown+-p+now · · Score: 1

      He specifically refers to the alternative syntax for PHP, which is stuff like:

      if ($a == 1):
      ...
      endif;

      i.e. a colon instead of the opening curly brace, and a keyword instead of the closing brace. This makes sense for PHP templates, because it can be hard to figure out what a standalone "}" after half a page of HTML refers to. But I think it's rather arguable whether it is more readable than braces when it's all just code.

    24. Re:Alternative syntax by shutdown+-p+now · · Score: 1

      Modern VB is actually quite legible if verbose. Though this has more to do with the choice of keywords - it generally uses plain English over specialized terms, so e.g. "abstract" on a method in C# becomes "MustOverride" in VB, and "static" class members become "Shared".

    25. Re:Alternative syntax by Hognoxious · · Score: 1

      Serves them goddam right. It should have been called something like hIntWndPtrPtrArPtrLambda.

      --
      Confucius say, "Find worm in apple - bad. Find half a worm - worse."
  15. Bitfield layout portability or lack thereof by tepples · · Score: 1

    I was under the impression that bitfield layout was implementation-defined, and that's undesirable if I want my project to compile on different architectures. The page you linked includes the phrase "Microsoft Specific" around anything mentioning layout, which illustrates my point.

    I was also under the impression that code generated by compilers for reading and writing bitfields was still dog slow. Has this changed?

    1. Re:Bitfield layout portability or lack thereof by daid303 · · Score: 1

      You are basically saying. "I don't want C++, I want C!"

    2. Re:Bitfield layout portability or lack thereof by tepples · · Score: 1

      So how would you recommend writing a parser for a binary file format that uses bitfields without this parser breaking on another platform? Perhaps if C is the best way to write such a parser, I should write this parser in C and the rest of the program in C++. Is that what you're basically saying?

    3. Re:Bitfield layout portability or lack thereof by daid303 · · Score: 1

      You deal with the bitfields the same way as you deal with all other binary data. You read it, and then put it in the right member. Bitfields are not some magic way where you can map a structure on a file. You should never EVER do that. Read a byte, test the bits you want (with classic C style binary ands) and save the results in bitfield values. There is no reason why the mapping on disk should ever be the same as the mapping in memory.

    4. Re:Bitfield layout portability or lack thereof by Arlet · · Score: 1

      There is no reason why the mapping on disk should ever be the same as the mapping in memory.

      Performance. If the mappings are the same, you can copy large amounts of binary data without having to process individual bits.

  16. Re:Cool! Meanwhile... by Per+Wigren · · Score: 1

    Yeah, if we just ignore C++11 the world's problems will go away.

    --
    My other account has a 3-digit UID.
  17. C++11one!1 by Anonymous Coward · · Score: 0

    Is APK in charge of their naming convention or something?

    1. Re:C++11one!1 by Anonymous Coward · · Score: 0

      no, Lulzsec :)

    2. Re:C++11one!1 by Anonymous Coward · · Score: 0

      I did wonder why they added /etc/hosts support...

    3. Re:C++11one!1 by Anonymous Coward · · Score: 0

      JUST be glad he DIDN'T write the standard!!!

      PS => You can probably attribute the overloaded use of '&' to him.

    4. Re:C++11one!1 by Anonymous Coward · · Score: 0

      You forgot to highlight every other sentence in bold and quote 50 different sources and other posts that in your own twisted view backup your claims somehow.

  18. Re:Cool! Meanwhile... by Anonymous Coward · · Score: 0

    Good luck with C++ 11 when you're stuck out in a field tending the crops for your lord, serf!

  19. See wikipedia by Anonymous Coward · · Score: 3, Informative
    1. Re:See wikipedia by kikito · · Score: 1

      Thanks. I wish that list was longer, but it's better than nothing.

  20. The purpose for these changes. by Anonymous Coward · · Score: 0

    They'll be using it to implement HTML 5.

  21. 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
    1. Re:Design by Committee by Anonymous Coward · · Score: 0

      It may be design by committee, but that doesn't mean it is suffering from the common problems that 'design by committee' is known for.

    2. Re:Design by Committee by rmstar · · Score: 1

      Now C++ is the ultimate example of a design by committee language. And that committee is huge.

      Huge indeed, but judging by the results, not particularly good.

      A doc that needs to be read by more people is the C++ Frequently Questioned Answers.

    3. Re:Design by Committee by david_thornley · · Score: 1

      A doc that needs to be ignored is the FQA. The author seems to have some sort of thing about denigrating C++, and either doesn't know what he's talking about or lies a lot.

      I went through one random section carefully. (If necessary, I can go through another one carefully and report.) It's bad.

      --
      "When you have eliminated the unacceptable, whatever is left, however improbable, must be the truthiness" - Holmes
    4. Re:Design by Committee by jeremyp · · Score: 1

      Yes, but it is though isn't it. C++ is now huge and it's virtually impossible to write a compliant compiler because its syntax is so complex.

      --
      All I want is a secure system where it's easy to do anything I want. Is that too much to ask ~~ Randall Munroe
    5. Re:Design by Committee by the_greywolf · · Score: 1

      The FQA gives the word "disingenuous" a bad name. The author spends a lot of time with red herrings, straw men, and minutiae, and never actually seems to have a point. Worse, many of his claims and assertions are flat-out wrong, or at the very least, badly misleading.

      Calling it a "pack of lies" would be unfair to packs of lies.

      --
      grey wolf
      LET FORTRAN DIE!
    6. Re:Design by Committee by TheRaven64 · · Score: 1

      No, C++ was suffering from those problems even when it was only designed by one guy...

      --
      I am TheRaven on Soylent News
    7. Re:Design by Committee by blair1q · · Score: 1

      ADA was designed by committee. C and C++ were evolved by committee.

    8. Re:Design by Committee by rmstar · · Score: 1

      The FQA gives the word "disingenuous" a bad name. The author spends a lot of time with red herrings, straw men, and minutiae, and never actually seems to have a point.

      The point is that the language sucks.

      Calling it a "pack of lies" would be unfair to packs of lies.

      While it may be inaccurate at some places, that is mostly due to feature drift (the FQA is somewhat old). The general theme is correct though, down to the technical details.

      Of course, it hurts C++ fans, but hey.

    9. Re:Design by Committee by David+Greene · · Score: 1

      The point is that the language sucks.

      If that's the point of the FQA, it has already disqualified itself as a useful source of information. These sorts of documents shouldn't be written with a partticular goal in mind. They should be an objective assessment of what's right and what's wrong with the subject.

      The general theme is correct though, down to the technical details.

      No, it isn't. A lot of that "feature drift" you talk about is exactly the set of things added to C++ to address its shortcomings.

      --

    10. Re:Design by Committee by Anonymous Coward · · Score: 0

      Why did C++ advocates sneer at the American Dental Association? Or did you mean American Diabetes Association? American Dietetic Association? American Disabilities Act?

      All of these are designed by committee. If you are referring to Ada, the programming language, please show some reverence. If something is ever named after you, for instance, what would you think if everyone typed it HUTTON (or worse, ALISTAIR). Ada, the programming language, is not an acronym. It is named after Ada Lovelace, credited with being the first computer programmer.

    11. Re:Design by Committee by shutdown+-p+now · · Score: 1

      The thing is that an equivalent FQA can be written for any other language out there (yes, even C) except possibly for Nil. Every language feature can be abused; if you focus on the abuse and ignore the benefits, the only logical conclusion is that the fewer features a language has, the better - and a perfect language would have zero features. Of course, you wouldn't be able to do anything with such a language, either, but hey, on the bright side it wouldn't have an FQA!

    12. Re:Design by Committee by gbjbaanb · · Score: 1

      *all* languages have such flawed features. The problem with the FQA is that is exaggerates them to the point of untruthfulness.

      I wonder if someone would like to come up with a FQA for your favoured language, you know it can be done with the same level of inventiveness.

    13. Re:Design by Committee by CSMoran · · Score: 1

      A doc that needs to be read by more people is the C++ Frequently Questioned Answers.

      Not really, that's just a lengthy rant by someone with a grudge, not much merit there.

      --
      Every end has half a stick.
    14. Re:Design by Committee by Alistair+Hutton · · Score: 1

      You win all the pedant points, victory is yours. Obviously I knew it was named after Miss Lovelace but for some reason I thought it was still spelled all capitalised when referring to the programming language. A quick Google search has disabused me of that notion.

      --
      Puzzle Daze is now my job
  22. Too late by Anonymous Coward · · Score: 0

    After many many years of C and C++, I jumped ship to C#. I don't really enjoy going back to C++ when I have to.

  23. D FTW by Anonymous Coward · · Score: 0

    C++ is a ugly beast, ok ok it was (is?) important and very used and it will always be around, but today we have far better choices than it, one of them being D (http://www.digitalmars.com/d/). Which receives collaboration from many number of C++ evangelist, to name one of them: Andrei Alexandrescu.

    1. Re:D FTW by rbarreira · · Score: 1

      Does it have a 64-bit compiler yet?

      --

      The AACS key is NOT 0xF606EEFD628B1CA427BEA93A9CA9773F
    2. Re:D FTW by marcosdumay · · Score: 1

      Isn't D copiled by GCC? Why would it not have a 64-bit compiler (you mean a compiler for ia64?)?

    3. Re:D FTW by abigor · · Score: 1

      Yes, D is good stuff indeed. You mentioned AA, but let's not forget Walter Bright, D's creator and all-around genius.

    4. Re:D FTW by rbarreira · · Score: 1

      Isn't D copiled by GCC? Why would it not have a 64-bit compiler (you mean a compiler for ia64?)?

      It's not that simple according to this page.

      I know someone who was developing a medium-sized program in D and decided to start over in C++ due to compiler bugs and general lack of compiler maturity.

      --

      The AACS key is NOT 0xF606EEFD628B1CA427BEA93A9CA9773F
    5. Re:D FTW by marcosdumay · · Score: 1

      Thanks for the explanation. What a hell of imcompatible versions... I guess that is how it feels to program in very new languages.

  24. 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 ifrag · · Score: 0

      Apparently the article neglected to mention it but you actually can write that:

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

      Looks like it was lost during editing or something.

      --
      Fear is the mind killer.
    3. Re:Does TFA actually explain things? by Anonymous Coward · · Score: 0

      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.

      Not anymore typically: COW is less efficient when the class must be thread safe. SSO eliminates many wasteful heap allocations too.

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

    5. Re:Does TFA actually explain things? by david_thornley · · Score: 1

      Yeah, the article lacked. I've been looking forward to "auto i = foo.begin()" for a long time; not only to save typing but to abstract things. "for (auto i = foo.begin(); i != foo.end(); ++i)" is a loop that works no matter what sort of container "foo" is.

      However, this Guru of the Week explains why copy-on-write strings don't do well in a multithreaded environment. Therefore, the move constructor is vital for top performance in string swapping. The move constructor or assignment from b to a means that b's guts are torn out and transplanted into a, with b getting default guts or something like that. Since this doesn't actually require anesthesia, it's a lot faster than carefully copying b's guts into a.

      I've been looking for good material on the differences between C++98 and C++0x, and this article really isn't it. http://www2.research.att.com/~bs/C++0xFAQ.html">Stroustrup's FAQ is better, but there's sections he hasn't written yet.

      --
      "When you have eliminated the unacceptable, whatever is left, however improbable, must be the truthiness" - Holmes
    6. Re:Does TFA actually explain things? by marcosdumay · · Score: 1

      "I thought standard library string implementations were supposed to be efficient, and include some sort of copy-on-write semantics..."

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

      That means that what you tought about the first example is now true. The default libraries will use copy-on-write semantics, and your unoptimized code will run faster after a recompile.

      Making a general porpouse library with copy-on-write semantics on C++ used to be quite hard (maybe impossible, I'm not sure). Now it will be viable.

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

    8. Re:Does TFA actually explain things? by larry+bagina · · Score: 1

      My understanding is the naive swap will still be naive (unless the compiler does some really fancy optimizing). The r-value version is tmp = std::move(b); b = std::move(a); a = std::move(tmp); or tmp = & b = & a = &

      --
      Do you even lift?

      These aren't the 'roids you're looking for.

    9. Re:Does TFA actually explain things? by siride · · Score: 1

      Well, in either case, you won't need to use the monstrosity. I'm not a C++ programmer anymore, so all I know is from reading this and a few other articles.

    10. Re:Does TFA actually explain things? by Anonymous Coward · · Score: 0

      You read my mind. I'm thinking "huh?" and then you point out the author can't communicate. Nope, 'he can't.

    11. Re:Does TFA actually explain things? by spongman · · Score: 1

      no, the article is very poor.

      if you want a good explanation of rvalue references, watch this video: rvalue references, perfect forwarding and associative containers. actually, just watch the whole series...

    12. Re:Does TFA actually explain things? by Anonymous Coward · · Score: 0

      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.

      No one does reference counted copy-on-write strings anymore, including the standard C++ library. They're grossly inefficient for multi-threaded environments.

    13. Re:Does TFA actually explain things? by Anonymous Coward · · Score: 0

      The idea behind move semantics is that the source in a lot of assignments (or copy constructions) are temporary. Consider the following:

      Widget x;
      Widget y = x;

      Now, in the copy construction, a copy of x's fields are made an stored in y. In the above case, a copy is probably what we want, since x is still accessible after the copy and its data needs to remain separate from y.

      Now, lets look at another case:

      Widget y = Widget();

      In this case, y is copy constructed from a temporary. A temporary widget is constructed, its data is copied, and then it is destroyed! Obviously, it would be a lot better to simply move the temporary's data into y directly. (Of course, the best choice would be to just default construct y, but I have seen less contrived examples where constructing from a temporary does happen.) If you declare two copy constructors, one using regular references and one using r-value references, the former will work as normal, but the latter will be invoked whenever we know that the source is a temporary and we know that moving is a better choice.

      Now, sure, if the Widget class implemented copy-on-write, like a lot of good STL libraries should do, it's not that bad, since only reference data is updated; the actual copying won't happen until either y or x is changed. However, I imagine most code doesn't use copy-on-write semantics. Move semantics and r-value references don't make anything automagically better. They are simply another tool to enable the programmer to make more efficient code where copying is concerned.

    14. Re:Does TFA actually explain things? by Anonymous Coward · · Score: 0

      Move semantics are really a micro optimization. Eg, yes the string library has efficient COW semantics, however move semantics lets even that overhead be avoided. The whole rvalue thing is feels pretty obscure, I think most people can avoid even knowing about it..

      The const_iterator example you picked from the article is the 'before' version, the auto version follows.

      auto is just syntactic sugar for decltype:

      auto foo = bar.begin();
      vs:
      decltype(bar.begin()) foo = bar.begin();

      Auto doesn't fit syntactically in the places decltype is meant to be used in.

      Due to how some of the modern C++ library design philosophy has evolved auto and decltype are quite important because you can write a template that calls a another overloaded template function and the return type is unknowable. Again, making design decisions like that tends to be a micro optimization.

      It helps to keep in mind that the people designing C++, and many of its users are concerned about every possible machine cycle. Many of the improvements make no sense when taken from, say, a Java developers perspective..

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

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

    16. Re:Does TFA actually explain things? by SanityInAnarchy · · Score: 1

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

      That wasn't why I was confused. I was confused because between the first part and the second part is this code:

      void func(const vector<int> &vi)
      {
      vector<int>::const_iterator ci=vi.begin();
      }

      I didn't see the point of that. It's possible the article has been fixed since then, or maybe I missed it the first time, because now it's pointing out the difference between that and the fact that you can now do:

      auto ci=vi.begin();

      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.

      Both of these, and more.

      Let me put it this way: The Lisps are, generally, very small languages. The syntax is incredibly small, and there are pretty much the bare minimum of language features, but they give you tools which allow you to build more interesting things.

      Ruby is about my sweet spot. It's a bit bigger, but there's still a lot of stuff which is moved to the standard library at best, rather than the core language. For example, there's a 'foreach' loop and a 'while' loop, and any other looping construct can be built using those, and can even look pretty, syntactically.

      Keeping the core language (especially the syntax) small means there are fewer surprises. It means it's much more likely I can read any arbitrary code snippet and either be confident that I know what's going on, or have a reasonable idea of where to look next.

      It's not just that C++ has a lot of features. It's that so many of them are baked into the language and the syntax, rather than a standard library. Even some of the libraries make this difficult by using things like macros instead of language constructs -- partly because the language isn't designed to make this sort of thing easy without macros.

      The best advice I've heard regarding C++ that it's actually a fairly nice language, if you deliberately restrict yourself to a reasonable subset. But that also means I can never be sure I'll be able to read someone else's C++ code without having to go back and learn more C++, since maybe they chose a different subset.

      The design of C++ was deliberately done to maintain the performance and efficiency of C. Adding objects has no effect on that...

      I'm not talking about performance, really. While C++ can feel "heavier" than C, that's purely subjective on my part, and probably has something to do with how much slower C++ compilers seem to be.

      I'm talking about the fact that aside from all of the new issues that come with the new features (slicing is my favorite), even the old C-style functionality doesn't always behave as expected, particularly when you're mixing it with C++. For example, in C, this would be reasonable:

      int do_something(int (*callback)(void *data), void *data);

      struct mystruct {
      ...
      };

      int mycallback(void *data) {
      struct mystruct *value = (struct mystruct *) data;
      ...
      }

      int main() {
      struct mystruct data;
      do_something(&mycallback, &data);
      }

      Phew, that's some ugly syntax, and I'm not entirely sure it'll compile -- certainly needs error checking, but that'd make it even uglier -- but hopefully it gets the point across. This is a pattern I picked up from languages like Ruby and Lisp, and it's about to get a lot easier in C++ with closures. But the relevant bit is that void pointer. This works perfectly well in C, which doesn't have inheritance. And the concept of a pointer being a single ad

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

      What? Really?

      That means that what you tought about the first example is now true.

      According to other posters, no it's not. There's a new syntax introduced which allows me to write code similar to the naive swap, but which runs efficiently. To be efficient, it requires support from the underlying object, but that object doesn't need to be COW at all -- in fact, it's a move, not a copy, the old version is invalidated at that point.

      Making a general porpouse library with copy-on-write semantics on C++ used to be quite hard

      Not really. Other posters have suggested that std::string might not use COW implementations because that's hard to make efficient and thread-safe, but it's certainly not difficult to do in a thread-unsafe way (trivial, really), and I can't see it being difficult to do (however inefficient) in a thread-safe way.

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

      I don't think inefficiency was the problem, none of the solutions attempted locking. The reasonable assumption was that if you did s=t to assign two strings, the programmer was responsible for knowing that both s and t were "owned" by the current thread, in that no other thread was looking at or modifying them. This is actually quite reasonable.

      The problem was this:

          const char* p = &s[n]; ... stuff here ...
          f(*p);

      This is impossible to do in a thread-safe way unless the thread "owns" not only s, but all the strings that were assigned to and from s. That was not reasonable. Most std::string implementations either ignored this, or they "uniquified" s when the pointer was taken, which removed the speed advantage of the reference counted implementation.

      IMHO what they did was a mistake. I would have preferred if they removed the ability to take a pointer into a string. All such uses are bad anyway, as they assume that "characters" are simple small units that should be looked at individually. The fact that stupid programmers have the ability to use this is destroying I18N by making UTF-8 and correct UTF-16 impossible and making decomposed characters not work.

    19. Re:Does TFA actually explain things? by shutdown+-p+now · · Score: 1

      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.

      Copy-on-write is very hard to implement for mutable strings which can have escaping references to them (iterators, but more importantly operator[], which returns a char&). You pretty much have to pessimistically assume that any attempt to obtain such a reference is a "write", because it might be one, and you have no way of finding it out later.

      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.

      This has nothing to do with dynamic typing. Even some dynamically typed languages require you to explicitly declare variables - you just don't specify the type.

      In case of C++, it has always been that you have to declare variables that you use. This makes their lifetimes easy to define - which, in a language with manual memory management, is a very important thing. "auto" doesn't change that.

      Does this make the "naiveswap" example automagically faster?

      No, you'd need an explicit move() there:

      void naiveswap(string &a, string & b) {
          string temp = a;
          a=std::move(b);
          b=std::move(temp);
      }

      Move constructors are automatically involved when the object being copied from is provably "going away" - in particular, when it's a temporary, or when it is used in a return statement.

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

      This means that whenever a container would do a copy before, and it knows that the source of the copy is going to be destroyed afterwards, it can now just do an explicit move instead. A textbook example is vector reallocating its internal buffer on resize() - before it would copy elements to new buffer, now it moves them.

      But hey, maybe I can write this

      You can. I have no idea why they have avoided the use of "auto" throughout the code after introducing it.

      That's cool. Kind of funny how it needs yet another language construct to do it

      decltype is not needed in that example, they just made a very contrived one (where auto would do just as well). Where you use decltype is in cases like:

      template<class T1, class T2>
      auto add(T1 x1, T2 x2) -> decltype(x1+x2) { return x1+x2; }

      This is still very contrived, but it gives the basic idea. You need decltype when you need to specify the type that is dependent on some other types which you don't know in advance (i.e. they are template parameters), but where you can't use simple type inference with auto because it's not a directly initialized variable.

      In practice, decltype is mostly used by library developers. To you as a user of those libraries, it all "just works".

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

      I dare say that the big thing about C++ are really templates, not classes/exceptions.

      Anyway, what's bloated about it? Remember, you don't pay for things that you don't use. If you want, you can write code that is just as efficient (literally: opcode for opcode) as in C. And still have templates and auto and other nifty stuff.

    20. Re:Does TFA actually explain things? by marcosdumay · · Score: 1

      Thread safety is quite an important requisite for a general porpouse library. You could already use COW on your code, but there is no good way that I'm aware of to implement it at the std libraries.

    21. Re:Does TFA actually explain things? by Ghostworks · · Score: 1

      The move semantics are useful for constructing new classes. Other functionality I'm less certain about. For example
      class NoCopy
      {
              NoCopy & operator =( const NoCopy & ) = delete;
              NoCopy ( const NoCopy & ) = delete;
      };

      as opposed to the old way of doing it:
      class NoCopy
      {
              private: NoCopy & operator =( const NoCopy & );
              private: NoCopy ( const NoCopy & );
      };

      I suppose you could call in "syntactic sugar", except it actually looks uglier and is harder to read for the lazy overloading of the "=" symbol. They could have just used a keyword, like "skip" or "omit" or "hide" in front of the call, and accomplished the same thing in a way the jives better with what people currently do, and is shorter than the alternative. TFA is pretty fuzzy on what "=default" entails, so I'm going to reserve judgment on that.

      The auto keyword could be useful, even if it steps on the toes of the existing auto keyword. Too much use of class names like

      sort<container<type>,container<type>::iterator<pointer<type>>>

      can make a class difficult to both read and write. Still, was "auto" really the only word for the job?

      TFA is not clear on if the new uniform initialization syntax is a one-size-fits-all fifth option, or if it's being forced as the only option. I doubt they're going to irritate nearly everyone by making it the only option, which would mean that programmers now have to learn the existing 4 methods of initialization, plus this new one to properly be able to read another person's code. If you ever have to look at a container class with instantiation options, good luck with that.

    22. Re:Does TFA actually explain things? by larry+bagina · · Score: 1
      make that: tmp = &&b; b = &&a; a = &&tmp;

      std::move(a) is equivalent to &&a;

      --
      Do you even lift?

      These aren't the 'roids you're looking for.

    23. Re:Does TFA actually explain things? by SanityInAnarchy · · Score: 1

      I dare say that the big thing about C++ are really templates, not classes/exceptions.

      Actually, now that I think about it, that and proper namespaces are pretty huge. Classes aren't that big a deal, but having decent containers in the standard library is very helpful. Exceptions are near the top of my list, though, because that instantly cuts the amount of error-handling code I have to write in half, while probably making my program twice as robust, since there's much less chance it'll just ignore an error and keep going.

      Anyway, what's bloated about it? Remember, you don't pay for things that you don't use.

      Yes, I do. I still need to learn about those things at least enough to read them when others use them.

      If you want, you can write code that is just as efficient (literally: opcode for opcode) as in C.

      Clearly "bloated" was the wrong term, as you're the second person to interpret this largely in terms of performance.

      The issue is that C++ is a big enough and complex enough language that very few people come close to actually understanding it, and I'd guess most people that use it sanely restrict themselves to a sane subset. This has a few very hazardous affects: First, if you're using a subset, this means that when you come across something someone else wrote, it's much harder to figure out what's going on. Second, it means there are tons of quirks in the language that are going to surprise you, no matter how well you think you know the subset you've staked out as "sane".

      A few things that surprised me, though I thought I had a decent understanding of C++:

      • Slicing. When I first encountered this, I thought I could get around it by allocating everything where this is likely to happen on the heap. Nope.
      • Typecasting a pointer can change the numerical address it points to. This means typecasting to void and then to a subclass or superclass of the original object doesn't work the way you expect.
      • Virtual destructors. Apparently, it's a good idea to define a virtual constructor which does nothing, even if you would otherwise not have to write a constructor, because the implicit one is not virtual.

      I suppose some of this is basic common knowledge, but really? This is as bad as Java fucking up the == operator. In addition, I need to either declare everything virtual and outside the function body (hoping the compiler is smart enough to inline when it makes sense, or turning that option on), or I need to think about low-level crap like that all the time despite that my build system, if not the compiler itself, almost always has enough information to figure it out -- and to make something not be inline, I need to put the class definition in a header and actually type the function in another file so that it's physically not inline, which means I'm typing the name of my class all through this file which is really nothing but defining methods on that class.

      So, tons of pointless verbosity (the auto keyword will help a little here), tons of low-level details the programmer is forced to either think about or adopt a suboptimal habit because the compiler couldn't be bothered, tons of cruft for backwards-compatibility (even with C)... I'm not talking about the resultant binary. The language itself is bloated, and the actual source code I'd be writing is bloated. I'll happily take a severe performance penalty where I can to avoid dealing with that bloat.

      --
      Don't thank God, thank a doctor!
    24. Re:Does TFA actually explain things? by shutdown+-p+now · · Score: 1

      Yes, I do. I still need to learn about those things at least enough to read them when others use them.

      On the bright side, that's job security - consider how few people will have the patience to read through all of that. ~

      Slicing. When I first encountered this, I thought I could get around it by allocating everything where this is likely to happen on the heap. Nope.

      Slicing is evil, no ifs or buts about that. I'm not against the concept as such, but they clearly should have made it an explicit operation.

      Typecasting a pointer can change the numerical address it points to. This means typecasting to void and then to a subclass or superclass of the original object doesn't work the way you expect.

      A good rule of thumb for dealing with object casts in C++ is to always use dynamic_cast. For upcasts, you want that runtime check anyway (to fail early if something goes wrong). For downcasts, it will compile to the same code as static_cast. For some casts (like downcasts from a virtual base class, or casts across the hierarchy), it works where static_cast doesn't even compile. And for cases like yours, as in e.g. downcast from void*, it will refuse to compile.

      But, yeah, C++ casts are somewhat messed up. I always thought that they should be cleanly separated into three groups: one for dealing with object casts (upcast, static downcast, and dynamic downcast/cross-cast), applicable to pointers/references to class types. The other group would be for conversions - int/float and such - including overloaded conversion operators. And the final group would be reinterpret_cast.

      Virtual destructors. Apparently, it's a good idea to define a virtual constructor which does nothing, even if you would otherwise not have to write a constructor, because the implicit one is not virtual.

      This is the consequence of "don't pay for what you don't use". Any virtual member means vtable, which makes instances fatter by the size of vtable pointer, adds extra code to constructor to initialize that pointer, makes calls to the member slower due to one extra level of indirection, and makes the class non-POD (meaning that many guarantees about layout of data members are dropped). All this cost goes unused if you never inherit from that class (like, say, for most STL classes).

      In even simpler terms, making implicit destructor virtual would break both source and binary compatibility with C, since now "struct foo { int bar; };" declared in C++ would have an extra hidden pointer at the beginning.

      . In addition, I need to either declare everything virtual and outside the function body (hoping the compiler is smart enough to inline when it makes sense

      You can perfectly well write a function body inline within the class, and also declare it "virtual" - there's no restriction here.

      Any C++ compiler will treat a call to such function as non-virtual when it's done directly on the instance of the object, rather than via a pointer or a reference. For pointer calls, most compilers also do some analysis to figure out if something can be made non-virtual. I know that VC++ with full program optimization mode on will check if a given class has any descendants, and if not, it will make any call to any member of that class non-virtual.

      - and to make something not be inline, I need to put the class definition in a header and actually type the function in another file so that it's physically not inline

      That doesn't guarantee that the function will not be inlined, if it is otherwise eligible for inlining. Any compiler worth its salt will inline it at least throughout the .cpp file it is declared in. Any compiler supporting full program optimization will inline it throughout the entire program.

      In fact, there's no way to prevent function from being inlined in standard C++. That's because it's optimiz

    25. Re:Does TFA actually explain things? by Anonymous Coward · · Score: 0

      COW is one of those deprecated implementations. It's horribly inefficient as soon as you add mutithreading, and pretty muc impossible to get right (iterators can get invalidated at any time).

      even code like:

      void f(const string& a, string & b){
      auto it1 = a.begin();
      auto it2 = b.begin(); //do something with it1...
      }
      This will use an invalid iterator it1 when called as f(v,v); as the second begin causes a copy to be made, so the old const_iterator is now invalid, probably pointing t the original copy.

      MSVC 6.0 had a non-thread-safe string class because of this kind of things.

      With move constructors you can have most of the advantages of COW without all the trouble.

    26. Re:Does TFA actually explain things? by SanityInAnarchy · · Score: 1

      On the bright side, that's job security - consider how few people will have the patience to read through all of that.

      Frankly, if I wanted job security, I'd be focused even more on mainframes -- stuff like COBOL. If they haven't replaced that stuff by now, they probably won't, and nobody wants to deal with that shit. For that matter, there's this tongue-in-cheek claim that C++ is a hoax, designed for job security.

      But I'm much more interested in having a job I actually like. I much prefer my job security is based, not on the amount of crap I'm willing to put up with, but on the quality of the work I actually do.

      Slicing is evil, no ifs or buts about that. I'm not against the concept as such, but they clearly should have made it an explicit operation.

      Except it's not clear that it could be, or that there wouldn't be some performance penalty if there was. Certainly, at compile-time, you don't always know what the real class is for each object you've got a reference to. At runtime, as I understand it, the idea is that the code which interacts with that object actually is just doing the exact same operations it would do on the parent class, with very little indirection except for (maybe) a virtual call.

      I'm not sure, though. C++ seems to allow quite a lot of copying, and probably at least partly for efficiency reasons -- you've got operator=, copy constructors, and now move constructors. I like the Ruby/Java model better, but it isn't without its costs -- the solution is that everything's on the heap, so every variable assignment is either a primitive copy or a reference assignment -- if you want to copy one object into another, you have to implement your own explicit methods to do so.

      So I'm not sure C++ actually made a mistake, given its goals, but I really don't like dealing with those semantics when I can avoid them.

      A good rule of thumb for dealing with object casts in C++ is to always use dynamic_cast.... And for cases like yours, as in e.g. downcast from void*, it will refuse to compile.

      So, not terribly helpful.

      The problem may well have been in my design. This was for a class, so I couldn't use something like Boost, so I implemented my own reference-counting pointers. I gave them the ability to be casted, though I remember having to give them their own syntax for this. The original solution was to have the backend object, where the count is actually stored, use a void pointer, and then perform the cast at the reference site -- which worked well, aside from this issue, and I did include code to check that I could make such a cast.

      What I eventually ended up doing to work around this problem was to effectively have the casts start to build a tree, so if I did something like:

      rc_ptr<X> x = new X();
      rc_ptr<Y> y = x.cast<Y>();
      rc_ptr<Z> z = y.cast<Z>();

      I would then, on every access to z, have the original X object cast to Y and then to Z. Effectively, z now has an rc_ptr to y inside it, which now has an rc_ptr to x.

      Ew. There has got to be a better way of doing that, but the best I can think of is to make the object graph even more complex by having a pointer to the real object stored somewhere for each type I need to access it as.

      Then again, do shared_ptrs allow casting at all? What do people actually use in situations like this? From what I could tell, it looks like people mostly just use pointers directly.

      This is the consequence of "don't pay for what you don't use". Any virtual member means vtable, which makes instances fatter by the size of vtable pointer, adds extra code to constructor to initialize that pointer, makes calls to the member slower due to one extra level of indirection, and makes the class non-POD (meaning that many guarantees about layout of d

      --
      Don't thank God, thank a doctor!
    27. Re:Does TFA actually explain things? by shutdown+-p+now · · Score: 1

      Except it's not clear that it could be, or that there wouldn't be some performance penalty if there was. Certainly, at compile-time, you don't always know what the real class is for each object you've got a reference to. At runtime, as I understand it, the idea is that the code which interacts with that object actually is just doing the exact same operations it would do on the parent class, with very little indirection except for (maybe) a virtual call.

      If you're assigning or initializing from B& to B, where B& is actually a reference to an object of some subclass D, that's not slicing. Slicing is when you assign from D (not a reference, but an object directly) to B, i.e.:

      struct B {};
      struct D:B{}'

      void foo(B b) {}

      int main() {
      D d;
      foo(d); // slicing
      }

      I'm not sure, though. C++ seems to allow quite a lot of copying, and probably at least partly for efficiency reasons -- you've got operator=, copy constructors, and now move constructors. I like the Ruby/Java model better, but it isn't without its costs -- the solution is that everything's on the heap, so every variable assignment is either a primitive copy or a reference assignment -- if you want to copy one object into another, you have to implement your own explicit methods to do so.

      Yes, you pretty much have to choose - either you don't have object types as such in the language, only reference types, or else you have to handle copying in all its facets. Interestingly enough, OOP languages have used reference-only model since the genesis of OOP - both Simula 67 and Smalltalk only had references.

      On the other hand, if you only have references, then your perf goes down very significantly. If you really implement all your primitives as references to boxed values, then even basic arithmetic has way too many indirections. In practice (i.e. in Python or Ruby), they normally do tagged references so that at least integers don't have to be boxed, but now you have the cost of checking for that tag bit to see if your reference is actually a value or not.

      Alternatively, you can do something like Java, where primitive types are values, and class types are references. But now there's no way for the programmer to extend the set of primitive types with something that looks similar - i.e. no way to have something like Complex<T> as a library type that otherwise behaves exactly like float or double.

      Then again, do shared_ptrs allow casting at all?

      Yes, though you need to use static_pointer_cast instead of static_cast (and similar for dynamic_cast etc).

      But shared_ptrs store refcount separately from the referenced object itself, so every shared_ptr consists of two pointers: one to object, and one to ref counter (actually, pointer to two ref counters - one is for weak_ptrs referencing the same object). That's why you can use shared_ptr with any type, even primitives like ints, despite them obviously not having any preallocated storage for the counter.

      So when you do static_pointer_cast from shared_ptr<B> to shared_ptr<D>, it just does normal static_cast for object pointer (so it's up to you to make sure that it is correct); ref counters do not depend on the type of pointed objects, so it can work with them directly without any casts.

      hat do people actually use in situations like this? From what I could tell, it looks like people mostly just use pointers directly.

      For a long time, shared_ptr only existed in Boost. Now Boost is a popular library, but still not used in many places, and for third-party libraries depending on it is undesirable. So in effect the only portable smart pointer was auto_ptr, which is only usable for very basic stuff. It was only in 2005 that shared_ptr was actually standardized as part of TR1, and it took a while for implement

    28. Re:Does TFA actually explain things? by Anonymous Coward · · Score: 0

      The fact that stupid programmers have the ability to use this

      Nothing about taking an address to std::string storage precludes i18n. The exact opposite is true; if it were not possible to take an address then the use of std::string would be precluded. C++ is understood to be capable of integration with non-C++ interfaces; interfaces that are incapable of directly interpreting std::string in any meaningful way including hardware, other software platforms and every conceivable form of digital communication, whether i18n aware or not. C++ does not compromise its roots as a systems programming language, even if it means low talent application programmers are permitted get their paws wrapped around the gears.

    29. Re:Does TFA actually explain things? by SanityInAnarchy · · Score: 1

      If you're assigning or initializing from B& to B, where B& is actually a reference to an object of some subclass D, that's not slicing. Slicing is when you assign from D (not a reference, but an object directly) to B...

      Erm... that seems entirely backwards. Your example is indeed slicing, but if I assign from a reference to some subclass D, to a local object (or to another reference) of some superclass B, both of those operations will eventually call the copy constructor or assignment operator, which means they'll be creating a new object of type B which won't have all the fields of type D.

      Isn't that what's meant by slicing -- that you're getting a new "copy" of some subclass object, but the copy is in the parent class and loses some things?

      As I understand it:

      class B{}; class D:B{};

      int main() {
      D d;
      B b = d; // slicing
      B &bref = b; // not slicing
      B &bref2 = d; // not slicing
      D &dref = d; // not slicing
      bref = dref; // slicing!
      bref = bref2; // also slicing!
      }

      Am I missing something?

      On the other hand, if you only have references, then your perf goes down very significantly. If you really implement all your primitives as references to boxed values, then even basic arithmetic has way too many indirections. In practice (i.e. in Python or Ruby), they normally do tagged references so that at least integers don't have to be boxed, but now you have the cost of checking for that tag bit to see if your reference is actually a value or not.

      All true, so far. It's interesting to note how performance improves -- sometimes it improves by deliberately killing things, like JRuby's experimental fast math options. (Ruby has open classes and integers, despite being tagged references, are really objects from a semantic point of view, so you can redefine addition. If you disallow that, JRuby makes some aggressive optimizations to make primitive math almost as fast, if not actually as fast, as Java primitive math.) But sometimes, it improves by making smarter compilers and VMs.

      My philosophy lately is, 99% of my code could take a thousandfold performance hit and nobody would care. The remaining 1%, I'll rewrite in C.

      Alternatively, you can do something like Java, where primitive types are values, and class types are references. But now there's no way for the programmer to extend the set of primitive types with something that looks similar - i.e. no way to have something like Complex as a library type that otherwise behaves exactly like float or double.

      It's worse than that. Java's == operator really means "compare reference or primitive". So you have to use Object.equals() when you actually have at least one object, but testing for null requires == anyway. Since == works on primitives, it's probably the first thing most Java newbies will learn, and it even works, sometimes, with actual objects like Strings.

      An explicit design consideration for C++ was that it should be able to use C libraries with no or minimal changes. This, in particular, means that it should be able to parse C header files, and provide identical data representation.

      I can't remember where, but I've had to do extern "C" anyway, so we don't really have this.

      This would actually be a good warning: if we're using "delete" on an operand of type B*, and it has known derived classes and no virtual destructor, then warn.

      Helpful, but now we have two additional problems. First, you don't always know about derived classes -- suppose you're writing a library, do you need to also include a test case for everything and check warnings on that? Second, even when warnings are fatal (often a good

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

      A read-only pointer would be ok (well it is true that a C function could write to the pointer, but it would be easy to say that is disallowed).

      The problem is the ability to assign to the pointer, which serves no purpose except to replace characters. And I think the idea that you can "replace a character" is what makes I18N not work.

    31. Re:Does TFA actually explain things? by shutdown+-p+now · · Score: 1

      Am I missing something?

      Not really, since there's no strict definition of slicing. That said, the only debated example among yours is the last one, where both sides of assignment are of static type B. I prefer the definition of slicing which restricts it to cases when the right side of assignment is statically known to have a derived type. More generally speaking, in this definition, slicing is not really assignment or construction as such, but rather the implicit conversion from D& to B& that occurs right before it.

      . A warning would be nice, though, and I think you do get warnings.

      Nope, since otherwise a very common C idiom, namely:

      int* p = malloc(sizeof(int) * 10); // malloc returns void*

      would give warnings.

      I don't remember about unions or enums, but structs only had their own namespace because you had to use the keyword 'struct' in front of just about anything you did with it. May as well name things struct_foo anyway.

      It's the exact same thing for enums and unions. The non-obvious thing here is that the names can overlap - i.e. it's perfectly legal to have a variable "foo" or (a typedef "foo"), and a tagged type like "struct foo" (or "enum foo" or "union foo") within the same scope - that's what I meant by "different namespaces". On the other hand, you cannot have "struct foo" and "union foo" in the same scope, despite the tags being different.

      In practice everyone writes it like so:

      typedef struct {
      ...
      } foo;
       
      foo x; // no struct needed anymore

      The only API I can think of where they didn't use the typedef trick are BSD sockets, which is why you have to write "struct sockaddr" etc everywhere.

      A lot of this can be simplified by accepting that arrays are pointers, and that the array syntax is at best sugar for pointer arithmetic.

      But arrays aren't pointers. Array values decay to pointers in most contexts, and array types decay to pointer types when used directly in function signatures, but you can still have e.g.:

      int* (*a)[10]; // pointer to array of 10 pointers to int

      and this would be a type different from, and incompatible to, int***. Now throw in function types, and it gets real messy real fast. Something like int*** is not a problem - it reads in a straightforward way right-to-left. But when you have arrays and functions, you have to jump back and forth, changing direction as you go, to parse the declaration.

      I suppose, but there really isn't a good answer there -- having a large unsigned value suddenly become negative isn't good either. The only other option is to do bounds-checking,

      Or just prohibit mixed operations - if you want one, an explicit cast should be in order.

      This can sneak up in some very unsuspecting ways, more so in C++ where you have a richer library, and types are implicit in expressions more often. Consider this simplistic code computing an average value of a vector:

      int a[] = { -1, 2, -3 };
      std::vector<int> v(&a[0], &a[3]);
      int a = std::accumulate(v.begin(), v.end()) / v.size();

      This will trigger unsigned overflow, because v.size() is of type size_t, which is always unsigned; and sum of vector elements is negative. So it ends up computing -2/3u, which is unsigned(-2)/3u, which is (on a 32-bit machine) 0xFFFFFFFE/3u, so you end up with a large positive signed (due to implicit conversion when assigning to a) number. What's even nastier is that you will get correct results on many input values while testing - so long as sum of elements is positive, everything is good.

      Of course, you could get into the same trap in C with array and sizeof.

    32. Re:Does TFA actually explain things? by SanityInAnarchy · · Score: 1

      That said, the only debated example among yours is the last one, where both sides of assignment are of static type B.

      If by "static" you mean the reference type, I suppose that's true, but the right reference in that case is still pointing to an object of type D, and exactly the same operation (and loss of information) is going to happen.

      Nope, since otherwise a very common C idiom, namely:

      int* p = malloc(sizeof(int) * 10); // malloc returns void*

      would give warnings.

      Ah, you're right. For some reason, I thought it was being exceptionally smart with malloc. Turns out I was thinking of printf.

      However, when I use g++ -Wall instead of gcc -Wall, it does generate warnings, and it does so without any sort of magic to make malloc not generate warnings. That makes sense -- in C++, you'd use new instead of malloc anyway.

      The non-obvious thing here is that the names can overlap - i.e. it's perfectly legal to have a variable "foo" or (a typedef "foo"), and a tagged type like "struct foo" (or "enum foo" or "union foo") within the same scope - that's what I meant by "different namespaces". On the other hand, you cannot have "struct foo" and "union foo" in the same scope, despite the tags being different.

      That is surprising. But hey, at least this is something which would be caught by the compiler, right?

      But arrays aren't pointers. Array values decay to pointers in most contexts, and array types decay to pointer types when used directly in function signatures, but you can still have e.g.:

      int* (*a)[10]; // pointer to array of 10 pointers to int

      and this would be a type different from, and incompatible to, int***.

      In what way is it meaningfully different? My understanding was that the array syntax, aside from being a useful shortcut for pointer arithmetic, is mostly about allocating arrays of things on the stack. Other than that, the difference is whether you've allocated space for a single value or an array, so I'm not seeing how I couldn't build a pointer to an array of pointers to int using int*** and malloc.

      Or just prohibit mixed operations - if you want one, an explicit cast should be in order.

      Or a warning, which I thought you'd get, but nope.

      --
      Don't thank God, thank a doctor!
    33. Re:Does TFA actually explain things? by shutdown+-p+now · · Score: 1

      However, when I use g++ -Wall instead of gcc -Wall, it does generate warnings, and it does so without any sort of magic to make malloc not generate warnings. That makes sense -- in C++, you'd use new instead of malloc anyway.

      In C++ that would be an error regardless of -Wall anyway, since it doesn't have implicit cast from void* (thank heaven!)

      In what way is it meaningfully different? My understanding was that the array syntax, aside from being a useful shortcut for pointer arithmetic, is mostly about allocating arrays of things on the stack. Other than that, the difference is whether you've allocated space for a single value or an array, so I'm not seeing how I couldn't build a pointer to an array of pointers to int using int*** and malloc.

      On representation level, int*(*)[10] is normally identical to int**, because int(*)[10] is normally identical to int* (it doesn't really matter if you point to some random int, or to an int which happens to be the first element of an array - it's still a pointer to int; bits are the same).

      However, it is different on type system level. If you declare your function thus:

      void foo(int (*a)[10]);

      then that array does not decay into pointer, and you can only pass to it a pointer to an array of 10 ints. So:

      int a[10], b[5], c;
      foo(&a); // type of &a is int(*)[10], valid call
      foo(&b); // type of &b is int(*)[5], type mismatch
      foo(&c); // type of &c is int*, type mismatch

      On implementation level, this can also matter. When the compiler sees int(*)[10], it knows that there must be 10 elements there; if someone passed fewer than that via an explicit cast, it is undefined behavior per spec. Thus, the compiler can speculatively fetch all 10 elements in advance even if the code didn't use them yet, and even if it is not guaranteed to ever use them, e.g. when you have a conditional:

      void foo(int (*a)[10]) {
        if ((*a)[0] != 0) {
          ++(*a)[9];
        }
      }

      Sometimes it is reasonable to assume that condition is true more often than not, and then more efficient instruction sequence can be generated if you're fetching the entire array, or at least a bigger chunk of it than just one element.

      Were foo declared as foo(int*), this couldn't be done, because it is not U.B. to call such a function with any int*. U.B. only happens for array smaller than 10 elements if the conditional is hit, and the compiler must generate code that will not fail otherwise. So it has to load a[0] separately, check for zero, and then and only then it may load the rest of the array.

      In C99 there's also "static" for array sizes:

      void foo(int a[static 10]);

      This is mostly same as int(*a)[10], but in addition to everything said above, it also cannot be null - so, again, the compiler is free to use this fact to optimize by prefetching array elements up to the amount specified without doing any null checks at all.

      I can't give a real-world code example where such optimization would happen right out of my head, but I recall it was discussed in comp.lang.c, and someone did come up with such an example on gcc.

    34. Re:Does TFA actually explain things? by Anonymous Coward · · Score: 0

      Again, this is incorrect. A writable pointer does not preclude i18n operations. For instance, a std::string may be resize()-ed to an arbitrary capacity and then have its buffer written by any mechanism capable of operating on a memory location, including anything that generates i18n output. One may even replace the allocator entirely and, for instance, represent the contents of ROM or some volatile memory area as std::string.

      I've concluded that you simply don't comprehend the imperatives of C/C++ language design. If std::string were not writable through a pointer it would not belong among the tools C++ provides. Until you understand why you're best to avoid C/C++, and avoid advising anyone else about these languages as well.

    35. Re:Does TFA actually explain things? by spitzak · · Score: 1

      I use std::string all the time. 99.999% of the manipulations are string append and string copy. push_back is also useful for building strings occasionally, for some reason you think this is done by "resize the string first and then assign to it". You may be confusing resize with reserve.

      My objection is to the idea that string[N] = 'c' is a useful operation. Not to string.push_back('c') or string+'c' or 'c'+string or iterator =string.find('c') or a bunch of other things you seem to think I am complaining about.

      Assigning a character makes assumptions that the replacable units of a string are exactly the same size. This is not true for Unicode and not true for UTF-8 or UTF-16 even for simple precomposed characters. It also assumes there is 1:1 mapping from old to new characters, such as lowercaseuppercase, which is certainly false for a lot of languages.

    36. Re:Does TFA actually explain things? by Anonymous Coward · · Score: 0

      for some reason you think this is done by "resize the string first and then assign to it"

      This is a perfectly valid technique when consuming output from a system that accepts a writable pointer. Specifically, when one can predict the maximum possible number of elements of a std::string for some known number of characters of a given encoding, one may then apply std::string.resize() (and most certainly NOT std::string.reserve(),) pass the pointer to the writer (POSIX iconv() for example) and then adjust the std::string down to the now precisely known element size of the result.

      This technique avoids an unnecessary copy operation (write to some maximally sized temporary buffer then have the std::string ctor copy the buffer contents after conversion) typically written by coders that don't fully understand the tools they're using. Whether the tailing unused space in a thus assigned std::string buffer is reclaimed (for space) or not (for speed) or follows some other policy (a reserved buffer that involves no memory management at all, for example) is left entirely at the discretion of the implementer.

      Assigning a character makes assumptions that the replacable (sic) units of a string are exactly the same size.

      std::string does not offer, imply or implement any knowledge of variable-width encoding. Any code making the assumption that the possibly variable-width characters in any buffer all have uniform length is in error, whether the buffer is managed by std::string or not. You're complaint, therefore, has no relevance to std::string, and std::string.operator[] is not impeached.

      Consider how the Dinkumware documentation describes <string>:

      The template class describes an object that controls a varying-length sequence of elements of type Elem

      std::string does not correctly manipulate the composed characters of a variable-width encoded unicode string. It does not imply that it does this. It is a string in the 'sequence of elements' sense. The fact that you and others conflate the Unicode notion of a sequence of variable-width characters with the C++ std::string notion of a 'sequence of [uniform] elements is, again, a lack of understanding.

      Perhaps you should instead complain that C++ lacks a <unicode_text> template that does the thing you wish, even including a variable-width character aware operator[] that works as you intend. In any case, std::string is fine as is, or at least does not suffer the flaws you claim it does.

    37. Re:Does TFA actually explain things? by spitzak · · Score: 1

      Supposedly reserve() followed by push_back() calls will produce an efficient writable string. However I believe the Windows version was screwed up and this did not produce anything efficient (basically it ignored reserve()). Probably more to the point, this was useless if you had existing code that wrote to a char* pointer, which I think is the usage you are interested in.

      The usage you want, where the entire contents of the string are written (rather than a replacement where some of the old contents are preserved), it would be possible to make work with a copy-on-write std::string. The cleanest I can think of is to make a writable_data() that makes a unique copy and does a resize() to the desired size as an atomic operation. Something like this:

            insure this thread is the only one using s; barrier;
            s.erase(); // this makes writable_data() not have to copy previous data
            char* p = s.writable_data(n); // atomic resize(n) except data is garbage, but unique buffer
            c_function(p); // write the data into the string
            barrier; s can now be read by multiple threads again;

      The reason for a new call is that resize() will waste time writing zeros to the buffer, and does guarantee a unique buffer (ie if the string is already the right size it does nothing).

      I would then have made data() and operator[] return const so they cannot be used to modify the string.

      The usage I was complaining about was not what you are asking for. What I would have liked to prevent was things like in-place toupper() implementations. First of all they prevent copy-on-write strings. Also they assume upper and lower case are exactly the same number of bytes, can be converted by replacing single bytes, and the conversion is invertible. With these changes it would not be possible to write such things, the programmer would then have to construct a new string with the toupper() result, allowing length changes and not destroying the old string.

  25. STL by Anonymous Coward · · Score: 0

    C++ is a brilliant language at its core. The only glaring flaw was the default copy constructor and the woes of casting with multiple inheritance. Looking back, the redundant header vs. implementation file declarations is also a bit tedious. However, I'm willing to overlook these as minor flaws in an otherwise good standard.

    Sadly, STL and the standard C++ library are C++'s Achilles Heel. The container libraries were overly complex and suffered the woes of C++ template limitations. Remember those STL container compiler errors where a single type name requires the entire screen to render? iostream while innovative ultimately proved less practical than stdio, and is not as good as contemporary solutions when it comes to string localization, where parameter position is locale dependent.

    Most importantly, the C++ library is woefully inadequate. What makes Java, .NET, Pearl, Python, etc so great is the library support. In my opinion, way too much emphasis was placed on garbage collection in discussions around C++, and not enough around robust library. To be fair, platform issues back then made this a big challenge. However, had their been an effort to create an industry standard (free) robust library for C++ that was as feature rich as Java and Net, we'd see more C++ programming today. (Yeah, I know there were attempts at this, but none of them made it into the standard.)

    As a C++ programmer who went on to projects in the managed-runtime languages, and recently due to platform requirements has returned to active C/C++ development, I am amazed at how my experiences with those higher level languages now influences my C++ writing. I credit those Java and .NET experiences with helping me now avoid all of the C++ pitfalls that lead to problems. The resulting C++ is much more elegant than what I used to write. I enjoy the raw power of native code, although for most applications, it is not practical.

  26. Re:Cool! Meanwhile... by Per+Wigren · · Score: 1

    While you live your life in fear for a hypothetical future scenario, I'll try to live a happy life in the present instead. If your fears come true, we'll probably die at about the same time anyway.

    --
    My other account has a 3-digit UID.
  27. Shouldn't they call this... by Trailer+Trash · · Score: 1

    C+=10
    ?

  28. Ignore this article by MobyDisk · · Score: 1

    Do not read this article, it makes C++0x look bad by giving terrible examples of the new features. Even features I've been excited about look stupid after reading this. The article shows how *not* to use a lambda expression. A regular for loop would be better here. Using "auto" on int and long does work, but defeats the purpose. The second example of auto doesn't even make sense since it doesn't actually include the word auto. It should be something more like: auto ci=vi.begin();

    Just ignore this and go to Wikipedia or Google.

  29. 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.
    1. Re:Why is a garbage collector even needed? by Anonymous Coward · · Score: 1

      Why is a compiler needed? Good coders should be able to use assembly directly. Is this so that everyone can start sloppy coding and forget about register allocation? It should be done right in the first place.

      On a serious note: if I've got to "use smart pointers" (read: implement a reference-counting garbage collector myself, because that's what smart pointers are) to make up for a deficiency in the language, then why the hell does operator new() return a "dumb pointer"? If I should be using STL containers rather than arrays, then why is argv an array of char arrays rather than a std::vector? Why does "std::string fullpath = path + "/" + filename " work for std::string path and char* filename, but fails for char* path and std::string filename? Why, in short, is your language such a Goddamn mess?

    2. Re:Why is a garbage collector even needed? by Anonymous Coward · · Score: 0

      Yes that is what people want. That is why they are asking for it. They want to be sloppy.

      Now I see where you are coming from. It really does not fit the c++ which like c but a bit more. As C is pretty simplistic in its memory allocations.

      Now an *OPTIONAL* GC type thing inside the framework. That could be interesting...

      In some cases GC will smoke speed wise regular malloc/free new/delete methods. First off you can possibly do the underlying free on a separate thread. Secondly you can batch them together when 'idle' is going on. You can also instead of removing 1 block of memory you could get rid of 200 all at once instead of a bunch of small calls. You can trade memory for time and speed.

      Also its the 'good C++ code...' bit that gets everyone. Even those of us who have been using it for years.

    3. Re:Why is a garbage collector even needed? by Anonymous Coward · · Score: 1

      A garbage collector is definitely required. Otherwise C++ applications just feel a bit weird. Too smooth, you know? It all just feels a bit "unnatural". A few pauses here and there make you feel that the application has more attitude, more human.

    4. Re:Why is a garbage collector even needed? by marcosdumay · · Score: 1

      Well, for example... Let's construct some class (call it Foo), and define the [ ][ ][ ] operation for it. That operation isn't a C++ operator, but a composition of them, but for that class it makes sense to use it. How would you do that?

      If Foo::[ ] and Foo::[ ][ ] are both types that don't need any extra memory from what there is in Foo, your task is easy, but if it is not, you'll need to use one of the several work arounds available at the language, and will have to write quite a lot of hard to read code. With a garbage collector, your task is easy again.

    5. Re:Why is a garbage collector even needed? by neonsignal · · Score: 1

      to make up for a deficiency in the language

      Sounds more like an opinion than having reasoned it out. Whether or not to have a garbage collector is not an oversight, but a deliberate decision in most languages for decades now. There are good reasons for not including one (such as unpredictability of memory usage and cpu time at run-time, difficulties of determining what is a pointer and what isn't, etc), and good reasons for including one (to remove a potential source of errors, to reclaim memory more efficiently than the application program might do so, and so on). On balance, the decision to not include a garbage collector in C++ is appropriate for this language, but isn't for others.

      why the hell does operator new() return a "dumb pointer"

      Because why have the overhead of a smart pointer if it is not always required? Smart pointers are quite useful, but that doesn't mean everyone should be forced to use them in every situation. This is a language that is sometimes used in bare metal contexts.

      why is argv an array of char arrays rather than a std::vector

      For the obvious reason that changing things like this would break existing compatibility with legacy C code. Clearly a language designed from scratch would not do this, but you are talking about a single declaration (of main) out of many thousands of lines in a typically application.

      Why does "std::string fullpath = path + "/" + filename " work for std::string path and char* filename, but fails for char* path and std::string filename?

      Because there never was any functionality to concatenate two char pointers. The prime reason that STL strings allow concatenation with a char pointer string is to support string literals; so if you are going to find fault, it is that there is no easy way to define std::string literals apart from initializing with a char * literal.

      Why, in short, is your language such a Goddamn mess?

      Because sometimes pragmatic considerations beat idealism.

    6. Re:Why is a garbage collector even needed? by Anonymous Coward · · Score: 0

      What is the argument about ABS in cars? People should learn how to brake properly.

    7. Re:Why is a garbage collector even needed? by Anonymous Coward · · Score: 0

      Unfortunately many people out there are not writing or maintaining good code.

    8. Re:Why is a garbage collector even needed? by LongearedBat · · Score: 1

      Totally with you on that. I'm primarily a Delphi developer, but the same applies. Delphi is not memory managed (save for interface references, sort of). By following the simple rule of "that which initialises also finalises" and always writing initialisation and finalisation together (ie. at the same time, so not writing in top-down order), I've found that I have very few memory leaks, end up with tidier code and, frankly, have fewer bugs overall, including AV's. The code is better. Garbage collection is nice and both have their own distinct uses, but garbage collection does encourage sloppier coding (though a good programmer won't fall for that encouragement ;) .

      Delphi's interface references are a simple way to handle garbage collection. (BTW, the rule here is: parameters are always local, so no const or var declarations for interface parameters.) If C++ uses the same system for its garbage collection, then that's fine. But if I want fully fledged garbage collection, then other languages specialise in that, such as Java and C# (which I also often use).

      There's a saying I once read: The problem with a houseboat is that it isn't a good house and it isn't a good boat.

      I guess what I'm trying to say here is that C++ should not try to compete with other languages in garbage collection. What C++ does, it does well, and what other languages do, they do well.

      Delphi is truly undervalued. One of the main reasons for it doing so poorly is that it attracted hordes of... useless developers (putting it kindly) who liked to cobble together components. Very few Delphi developers I've worked with actually knew and applied good programming techniques. The same plague is inflicting .Net, from what a manager friend tells me. Let not C++ suffer the same fate.

    9. Re:Why is a garbage collector even needed? by Mr+Z · · Score: 1

      Yeah, because most hum......................ans totally sto..........p and start tal............king with random p-p-p-p-p-p-p-pauses.

    10. Re:Why is a garbage collector even needed? by Anonymous Coward · · Score: 0

      Mod up.

      I dislike GC's like Java's that involve deletion at some unspecified later time. Ref-counting smart pointers give you most of the benefits, without making it hard to reason about memory usage. Just delete the object immediately when the last reference is released. That way, you have both automatic memory management and a useful destruction model.

      I'm sure the Java guys had good reasons for their approach but I have no idea what they were.

    11. Re:Why is a garbage collector even needed? by Anonymous Coward · · Score: 0

      The nice things about e.g. Java's garbage collector is the memory compactification and the extremely cheap memory allocation in contrast to C++'s expensive "new".
      But I don't see how you would get this in C++ even with an automatic garbage collector?!

    12. Re:Why is a garbage collector even needed? by cratermoon · · Score: 1

      For the obvious reason that changing things like this would break existing compatibility with legacy C code.

      Lemme guess. You didn't hear about the redefinition of the auto keyword? Or the deprecation of auto_ptr? Or any of the other things in the new standard that breaks existing compatibility with legacy C code?

    13. Re:Why is a garbage collector even needed? by Spykk · · Score: 1

      We need a language that doesn't have a garbage collector. Have you ever tried writing something that runs in a tight loop (games for example) in a managed language? If you do any dereferencing in your loop the garbage collector will hang unacceptably for awhile every few seconds or so making everything stutter. Instead of allocating a particle and then deleting it when you are done with it you have to keep a big pool of particles in memory at all times and reuse them. Delete operations that could have been spread out over several thousand frames get saved up and then all happen at the same time. Garbage collection is great for some applications, but forcing it into every language would be a mistake.

    14. Re:Why is a garbage collector even needed? by Anonymous Coward · · Score: 0

      I think you'll find a good answer here: http://www.digitalmars.com/d/2.0/garbage.html ;)

    15. Re:Why is a garbage collector even needed? by Anonymous Coward · · Score: 0

      reference counting is one form of garbage collection, it has shortcomings, like refernce cycles and atomic counting instructions.

    16. Re:Why is a garbage collector even needed? by sourcerror · · Score: 1

      I thought creating new objects in Java is especially expensive.
      Ref counting should have it's overhead, shouldn't it?

    17. Re:Why is a garbage collector even needed? by Eponymous+Bastard · · Score: 1

      GCs are very useful in a few cases. In particular if you have a graph data structure which can have cycles and holds no resources then a GC will save you a lot of work. As soon as you introduce cycles smart pointers and destructors stop being enough.

      Personally I think OO programs should avoid having cycles in their dependency graphs anyway. If Foo requires Bar to work and Bar requires Foo, which one do you destroy first? Foo might use Bar in its destructor and viceversa. GC'd languages resolve this by saying "we'll destroy them in whatever order we want, don't count on your references being valid". Smart pointers can solve this by declaring one of those as a weak reference, thereby making it obvious which one gets destroyed first.

      On the other hand if you're writing a compiler or some other graph-heavy program, having a free-form data structure with automatic GC where referents don't get destroyed while you hold them (no weak_ptrs) will save you a lot of trouble. The flip side is that you shouldn't let any of those objects hold onto external resources like open files, database connections, etc.

      So... GC for PODs and smart_ptr for OO. The lack of a generic C++ GC does present a problem, I think.

    18. Re:Why is a garbage collector even needed? by Anonymous Coward · · Score: 0

      The problem is that in multi-threaded code it can be impossible to determine when an object can be reliably destroyed.

      Therefore 'sloppy' code with a garbage collector, is more reliable than code that attempts to do it right.

    19. Re:Why is a garbage collector even needed? by Tyler+Durden · · Score: 1

      ..."use smart pointers" (read: implement a reference-counting garbage collector myself, because that's what smart pointers are)...

      No, smart pointers take care of the reference-counting garbage for you behind the scenes, actually. You're thinking of Objective-C.

      --
      Happy people make bad consumers.
    20. Re:Why is a garbage collector even needed? by shutdown+-p+now · · Score: 1

      If Foo::[ ] and Foo::[ ][ ] are both types that don't need any extra memory from what there is in Foo, your task is easy, but if it is not, you'll need to use one of the several work arounds available at the language, and will have to write quite a lot of hard to read code. With a garbage collector, your task is easy again.

      Even if you need extra memory, so what? All your operator[] will return the proxy objects by value, and they will be automatically destroyed at the end of the statement, same as any other temporary.

    21. Re:Why is a garbage collector even needed? by Anonymous Coward · · Score: 0

      STL doesn't work with shared_ptr/auto_ptr. It does with garbage collection.

    22. Re:Why is a garbage collector even needed? by inglorion_on_the_net · · Score: 1

      I feel the discussion about garbage collection has been held a few tens of thousands of times now, and I find your suggestion that people want a garbage collector so they can get away with sloppy code offensive.

      For those who don't know, there are good reasons to have automatic memory management, and most of the arguments against it (e.g. performance, predictable timing) are bogus (automatic memory management is not necessarily more or less performant or predictable than manual memory management). Here are some good reasons to have automatic memory management:

      1. Cleaner interfaces. Interfaces to library code often become more elegant and easier to use when you don't have to specify who owns allocated memory.

      2. Memory safety. Operations like free in C and delete in C++ break memory safety, because after performing them, the pointer they operated on should not be used anymore, but still can. By contrast, a garbage collector will only reclaim memory after it is no longer referenced, so references that do exist are always valid.

      3. Rapid development. Compared to manual memory management, automatic memory management can be expected to lead to less time spent writing code to manage memory, less time needed to think about where it should go, and less time finding and fixing bugs that are bound to crop up.

      For an example of how automatic memory management leads to cleaner interfaces, consider a function foo that returns a list of items in some undefined order. You want to present the items to the user in some specific order. If you have automatic memory management, you could write something along the lines of

      sort(foo(), [x,y]{ /* your sorting code here */})

      Without automatic memory management, this would leak both the list returned by foo and the closure used for sorting. So it would more likely become something like

      int sorting_predicate(T x, T y) { /* your sorting code here */ }
      list<T> temp_list = foo();
      list<T> result_list = sort(temp_list, sorting_predicate);
      free_list(temp_list);

      --
      Please correct me if I got my facts wrong.
    23. Re:Why is a garbage collector even needed? by Anonymous Coward · · Score: 0

      You can create objects on the stack. Its appropiete in some cases.

    24. Re:Why is a garbage collector even needed? by Ghostworks · · Score: 1

      As constructs get more complicated, so too does the question of what is garbage. For example, If you have a simple linked list with a head node, and that gets deleted, it makes sense for the head and all of the nodes linked from the head to be deleted. If you have a more complex dataset that tries to make effect use of space with copy-by-reference, then you have to keep track of how many pointers are linking to a piece of data. If you have a structure where "lower" nodes may point to "higher" nodes, forming loops, then you can get situations where the node is locked and never considered garbage, even though it is inaccessible to the user's program, and all the references to it are held by other nodes which are similarly inaccessible, and thus garbage.

      The problem of detecting these cyclical dependencies can be rather complicated, and there are a couple of ways you can go. Usually, you will have to store more data per node (say, a hierarchy number so that you know when a node is only being references by other, "lower" priority nodes), or use more computing power (say, a crawler process which actively looks for inaccessible cycles of dependencies on heap structures), or even require major program architecture (like a privileged, "border" set of pointers, which force object deletion when no so-privileged pointers link to the object). Garbage collection takes these architectural considerations and consolidates them, making the most efficient use of computer resources and liberating the programmer to worry just about the logic of his program, rather than the edge cases that could cause his program to accidentally choke to death on a some sort of heap memory tumor.

      It's overhead that's not always necessary. When it is necessary, programmers want a thoroughly-tested, centralized system to make that overhead as painless as possible.

    25. Re:Why is a garbage collector even needed? by neonsignal · · Score: 1

      Why do you think the auto keyword was chosen? Are you suggesting it would break compatibility less by adding adding a new keyword, or that one of the other keywords would have been a better choice?

      And since when does deprecation break existing code? Deprecation is just an advance warning that the feature will be removed some time in the future.

      It is not clear if you are arguing for more radical change, or less.

    26. Re:Why is a garbage collector even needed? by benhattman · · Score: 1

      C++ obviously doesn't NEED a garbage collector, just like it didn't need lambda expressions. They can, however, be incredibly useful if you want to write algorithms in certain ways. Here's a simple example. You've got an object you want to pass through your system, and you don't know who all owns it at any given time. It's a complex object, that even passes itself into some of its own member data.

      So, how do you manage that without a GC? You want to at least use smart pointers (shared_ptr), but that doesn't deal with the circular reference of A points to B points to A. You also don't know the lifetime of the object, because it's been passed all over the place in your program.

      Without a GC, you are forced in this situation down some paths you might not like. You can refactor your algorithm to prevent the cyclic references. You can hack in some code to look for this specific case and deal with it by removing one of the cyclic references. I guess you could write your own garbage collector. The point is, you may be forced to write a more awkward or less efficient algorithm just for lack of a GC.

      What I think C++ really needs is more of an optional garbage collector. Use gcnew (like the old managed C++ did) and you get back an object like gc_ptr. The gc_ptr is different that the other smart pointers, because you can't get the underlying pointer or reference object out of it, even though the -> operator would function about as expected. That would make the feature annoying enough to use, that hopefully people would pick another approach when applicable and use the gc_ptr only when necessary. It might give you the best of both worlds.

    27. Re:Why is a garbage collector even needed? by Anonymous Coward · · Score: 0

      The big advantage of GC (as I see it) is that you can returned allocated memory objects from functions and pass them around as much as you like. There are many times when I have wished for a real GC in my language. If you've got one, then more code can be written in a functional style than imperative style.

      RAII doesn't work for everything.

    28. Re:Why is a garbage collector even needed? by Zoxed · · Score: 1

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

      In a way you have answered your own question: in my humble 20+ years experience good code is hard to find in the real world !! I can't remember how many bugs I have fixed in *live code* that come from uninitialised vars, mixing "|" and "||", buffer overflows etc. None should exist in "Good Code", but they do.
      Same with garbage collection: there *should* be no garbage to collect, but there will be !!

    29. Re:Why is a garbage collector even needed? by CSMoran · · Score: 1

      Lemme guess, there are tons of programs using auto in the old syntax, right?

      --
      Every end has half a stick.
    30. Re:Why is a garbage collector even needed? by funky_vibes · · Score: 1

      A good language should as often as possible make sloppy code crash or produce severely unexpected results.
      That's the beauty of C.

      Less code is better than more code, and in the same spirit:
      No code is better than sloppy code.

      The further C++ moves in the direction of languages designed for morons (java, C#, PHP), the further we get from our objective of having systems that actually work.

      Let's start making the distinction between mission critical coders and all others. They can have their languages and we have ours in peace.

  30. linking improvements by Anonymous Coward · · Score: 0

    What about a standard for mangled symbol names (implicitly covering calling convention) to allow cross-compiler linking, and attributes for declaring symbols exported or imported from the library or module.

    1. Re:linking improvements by larry+bagina · · Score: 1

      intel has a c++ abi standard.

      --
      Do you even lift?

      These aren't the 'roids you're looking for.

  31. So, why should I care... by DdJ · · Score: 1

    ...if I'm not a C++ programmer today?

    I stated as a C programmer in the 1980s. I've used three different object-oriented extensions to C, and C++ was neither the first nor the best of them. I'm not in an industry (like video gaming) that pushes me toward C++ with any pressure at all. Every few years I take a look at C++ and conclude that it's safe for me to continue ignoring it.

    Is there anything different this time around that would change this, that's easy to explain to someone who's not already a C++ programmer, and doesn't have the context/history of one? Could someone please summarize?

    (Genuine and sincere question there, FWIW.)

    1. Re:So, why should I care... by david_thornley · · Score: 1

      If you're new to C++, this isn't going to matter much to you right now. It's a better C++, which is of considerable significance to me but not necessarily to you.

      It takes time for new features to filter into common use, and, even more, common instruction. For years after the 1998 standard, lots of C++ books used arrays and such rather than container templates. Stroustrup's introductory textbook, copyright 2009, uses raw pointers, for Turing's sake! Those things are dangerous, and shouldn't be used by beginners. Sure, shared_ptr wasn't in the standard yet, just the technical report, but it was easily available through the Boost smart pointers library.

      If you think of C++ as an object-oriented extension to C, you're already influenced by that problem. Templates are at least as important in modern C++, and less common in other languages. It started as a version of C with something like Simula 67 objects, yes, but that's not been its reason for existence for well over a decade now.

      What it means to you is that, if you ever do come back to C++, you'll be getting a better language out of the deal. That, I think, is the takeaway for you.

      --
      "When you have eliminated the unacceptable, whatever is left, however improbable, must be the truthiness" - Holmes
    2. Re:So, why should I care... by marcosdumay · · Score: 1

      The std libraries will get a lot easier to use. C++ will get the for(type element : container) construct, like Java, and there is now an "auto" type that is infered at compile time. Those are probably the differences that you'll see not being too much into C++.

      What there is in C++ that should make you look at it are the libraries, RAII, and templates. Only the libraries will change (ok, templates will get a bit better), so if they used to be the problem for you, take another look at them in the future.

    3. Re:So, why should I care... by DdJ · · Score: 1

      If you think of C++ as an object-oriented extension to C, you're already influenced by that problem. Templates are at least as important in modern C++, and less common in other languages. It started as a version of C with something like Simula 67 objects, yes, but that's not been its reason for existence for well over a decade now.

      I find this pretty interesting -- is there any chance you could elaborate?

      If I'm currently completely happy with C for some things, Ruby for some other things, Objective-C for some other things, and I'm mostly happy with Java for some other things, under what circumstances might I want to give C++ another look?

    4. Re:So, why should I care... by Anonymous Coward · · Score: 0

      I haven't looked at C++x11 but I suspect the answer is no. As Bill Gates said fifteen years about a much hyped version of Windows: "If you have no idea why you might need NT, you probably don't need NT". In other words the new version of C++ is probably more of an evolutionary rather than revolutionary advance - if you didn't need it before, you won't need it know.

      System programming above the OS level (including database engines) and video games are some of the slam-dunk uses for C++ today. Also, GUI apps where you don't want to incur the virtual machine overhead, or where you are bothered by the ease in which bytecode can be reverse engineered back into original source. (Microsoft Office is still almost entirely written in C++, ten years after the introduction of C#).

      As for the value added by C++ over ANSI C - I think it has to do with the programmer. Do you ALWAYS think in terms of layering your code to decouple different parts of your application or program from changes in other parts, or do you tend to be obsessed with raw performance? Or in just getting the job done. BTW this distinction seems to have only weak correlation with mathematical aptitude. If you are one of the latter two types, you probably would do as well or better in C as with C++. If you are of the first type, though, you will quickly learn to appreciate an object-oriented language like C++, which manages the tedious, error-prone bookkeeping you'd otherwise have to do in C by explicitly setting up arrays of function pointers and the like.

  32. Features, yes. Safety, still in denial. by Animats · · Score: 0

    Ah, the C++ committee. They've added lots of l33t features, and haven't fixed any of the safety problems. You can still get raw pointers. You still sometimes need them. The language-level arrays are still unsized, like C, and there will still be buffer overflows. (Yes, if you do everything the "C++ way", buffer overflows are much less likely. Now try to use the Linux API. There are too many places where the programmer has to be "very careful". People who think that's OK should be put on maintenance programming for a year.)

    C++ remains the only major language with hiding ("abstraction") but without pointer safety.

    1. Re:Features, yes. Safety, still in denial. by marcosdumay · · Score: 1

      "C++ remains the only major language with hiding ("abstraction") but without pointer safety."

      Yep, that happens to be what makes it usefull for some kinds of software. If you want a managed language, use one.

    2. Re:Features, yes. Safety, still in denial. by constpointertoconst · · Score: 1

      If an API is written in a way where the user has to be "very careful", then it isn't written very well. There might also be performance reasons but I've found that you are rarely absolutely required to sacrifice safety, readability, etc, to attain substantial performance gains if you truly know what you are doing.

      C++ is one of the more "safe" languages available if you use it properly. It's compile time safety features trump all other popular languages in my opinion (runtime safety is another story).

  33. Time for a flag day by tepples · · Score: 1

    They can't because it would break people's code

    Then perhaps C++ and Java are overdue for a flag day. Visual Basic had one from VB6 to VB.NET, and Python more recently had one from Python 2 to Python 3.

  34. GCC support matrix by xororand · · Score: 1

    GCC has supported many C++0x features for quite some time now.
    My personal favorites are the auto keyword, particularly when used with iterators, enum classes & lambda functions.
    Oh, and #include :
    uint32_t, int64_t,
    Many other features like regular expressions are neat but have been available with the Boost libraries for a long time anyway.

  35. *P.S. by xororand · · Score: 1

    That was supposed to be
    #include <cstdint>

    1. Re:*P.S. by jeremyp · · Score: 1

      You could have nicked the C99 stdint.h. I've just had a look at it and it looks like it should compile in C++.

      --
      All I want is a secure system where it's easy to do anything I want. Is that too much to ask ~~ Randall Munroe
    2. Re:*P.S. by shutdown+-p+now · · Score: 1

      There's no such thing as "the C99 stdint.h". The standard does not define what e.g. int32_t is typedef'd to, it just requires that stdint.h provides such a typedef. Therefore, stdint.h is always specific to an implementation, because that implementation knows that its e.g. int is 32-bit, and therefore it can typedef int int32_t.

      In case of gcc, we're really talking about one implementation. But then they have always supported stdint.h (and cstdint) in C++, since it was alread a part of C++ TR1.

  36. Welcome to the 20th century by ThirdPrize · · Score: 1

    What do you mean that wasn't the 1911 standard?

    --
    I have excellent Karma and I am not afraid to Troll it.
  37. Re:Cool! Meanwhile... by Nadaka · · Score: 1

    Obama and the democrats are slightly less in favor of serfdom than the republicans.

  38. Threading standard by turtle+graphics · · Score: 1

    One of the best things that I see as a CS educator is that the threading package is now part of the STL. Teaching threading using PTHREADS always hid the concepts in a layer of obscurity. And usually, if something's obscure when you teach it, it will be a source of mistakes for novices and pros alike. Just the simplicity of async() and the creating of threads and mutexes makes this worth the price of admission.

  39. ISO Standard or it didn't happen? by DragonWriter · · Score: 1

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

    The first sentence is true. It does not imply the second, however.. C++ was widely used in production before it became an ISO standard, so in one sense it was "out of development" before being standardized; on the other hand,it remains actively under development today (which is why we are talking about a new version of the standard), so no matter which side you look at it from, the first ISO standard isn't a good dividing line between the language "being in development" and it being in some other state. The first ISO standard for C++ wasn't the first iteration of the language in any meaningful sense, it was just the first ISO standard.

  40. C++ haters by Anonymous Coward · · Score: 0

    In soviet Russia, C++ hates you. Scratch that. C++ just hates you.

  41. 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.)

  42. C++ have had? by Anonymous Coward · · Score: 0
    Is there really a reason to write this as

    C++ have had...

    Rather than

    C++ has had...

    ?

    1. Re:C++ have had? by Cinder6 · · Score: 1

      C++ is one more than C, so, you see, it's plural...

      (Assuming C > 0)

      --
      If you can't convince them, convict them.
    2. Re:C++ have had? by RoverDaddy · · Score: 1

      I immediately take it as the British English tendency to treat 'names of entities' as plural, as in "Apple have been evil for less than 5 years".

      --
      RETURN without GOSUB in line 1050
    3. Re:C++ have had? by Anonymous Coward · · Score: 0

      but C++ is post-increment, so it would only be plural _after_ you read the sentence.

  43. Quip of the day by rmstar · · Score: 1

    C++ is the Lisp of Mordor - me

  44. C++ needs something else ... by Anonymous Coward · · Score: 0

    If Mozart wrote a Music Theory textbook, it would be delicious to read but impossible to use.

    C++ is a great language, but it's impossible to use because it is fussy and complex. Real programmers don't have time to waste fooling with it and don't need to prove their chops to anybody.

    Why didn't the C++ committee help to define a simple-to-use C++ scripting language subset, that we could actually use to write real-world code, quickly and efficiently?

    sc

    1. Re:C++ needs something else ... by constpointertoconst · · Score: 1

      I really hate that attitude regarding C++. Yes, C++ has a learning curve. C++ isn't necessarily the best solution to a given problem. But if you know how to use it, you will be very productive.

      Also from what I've seen, C++ can do just about anything that any other language can do, and more, in some fashion. To me, this makes C++ the best (but not only!) tool for most projects where I am not burdened by naysayers who refuse to learn a "difficult" language.

      You mentioned scripting languages. Scripting languages are great for a variety of uses, but they terrible for others. They don't scale. They don't have much or any compile-time safety. They are typically slow.

    2. Re:C++ needs something else ... by sourcerror · · Score: 1

      It comes from Java programmer, so be warned. (I don't know how much it applies to C# as well, as I am not very familiar with it. To be honest I don't feel that I'm know C++ well enough neither, but who does?)
      My problem with C++ is that it's syntax is too complex, so it's impossible to write decent auto-complete feature. (I'm not impressed with the Intellisense in VS C++; or the one CodeBlocks). Also, that causes error messages to be less helpful, and I guess many incompatibility between different compilers is caused by this fact.

      Also, the way it includes headers can be confusing at times, as putting classes in modules works different than putting functions in there. Also the fact, that it matters which direction declaration come feels archaic as well. (I don't feel it was justified to do things this way in the eighties. However I wasn't there writing compilers back then.)

      Of course, the garbage collection of Java makes it unsuited for real-time applications. (And the fact, that "finalize" methods are often not called at all.) And I'm not very happy, that JNI has such a big overhead, but I think Java got a lot of things right with it's simplicity. Also, although agile people like to bash Java, I don't see that it were unsuited to that methodology, as the corporate culture isn't there in the language per se. And the verbosity and staticness gains you better IDE features (better auto-complete and refactoring and cross-referencing support; also, it makes code written by others much easier to get familiar with).

      I wonder whether it would be possible to write a lower level Java, or standardise calling conventions for CPU acrhitectures yet to be created, without moving everything to a virtual machine.

    3. Re:C++ needs something else ... by constpointertoconst · · Score: 1

      Those are all fairly common concerns about C++, but primarily ones made by inexperienced C++ users.

      The complex syntax (particularly templates and the preprocessor) indeed presents a problem for writing helpful IDEs both in terms of autocomplete/refactoring and useful error reporting.

      There is a plugin for MSVC called Visual Assist X that does a much better job than (at least 2008's) Intellisense. It's not free but myself and people I work with find it indispensable. It handles almost everything very well except for particularly crazy preprocessed constructs.

      Header inclusion is really a very simple affair - all the #include directive does is paste the contents of the file in place. Everything else falls out of that. Forward declarations may seem archaic, but they allow you to be explicit about depending on skeletal declarations rather than full definitions (although this can admittedly get kludgy in some circumstances, e.g. typedefs), and they allow you to have a sort of cheat sheet of declarations that is separate from the implementation.

      I'm not sure what you mean by the direction of declarations. As long as you avoid unnecessarily cyclic dependencies (which should be easy if you keep definitions out of your headers), you should be fine. I'm also not sure what you mean about the difference between classes and functions in "modules". Both classes and functions can be "forward declared". Nothing needs to depend on the definition of a function, but you need to see the definition of a class if you want to do anything more with it than hold/pass pointers/references of its type. Declarations can be repeated as long as they are the same. Definitions can not be. (and neither can typedefs, which is indeed irritating, but the new standard does improve on typedefs in various ways).

      Java is built for virtual machines. By definition, I don't think it's possible to write a different sort of compiler that improves on the performance situation of a VM very much. If you were to attempt something like this, you'd be at best creating a subset of Java which essentially would be a restricted subset of C++ anyway, I think.

    4. Re:C++ needs something else ... by sourcerror · · Score: 1

      "Header inclusion is really a very simple affair - all the #include directive does is paste the contents of the file in place. Everything else falls out of that. Forward declarations may seem archaic, but they allow you to be explicit about depending on skeletal declarations rather than full definitions (although this can admittedly get kludgy in some circumstances, e.g. typedefs), and they allow you to have a sort of cheat sheet of declarations that is separate from the implementation."

      What I meant, when to extern and when not to. I once struggled to convert extern functions to class methods. I can't cite the example, but it was plenty confusing for me.

      And besides the language itself, the another problem is the standard library: it has so few things. Not even a proper String class that abstracts away character encoding, no standard way to create GUIs, parse XMLs. I had to do some small project in c++ recently, and I had to hunt for opensource libraries that do these, but unfortunately, the XML library used UTF-8, the GUI used UTF-16, and the free fonts I have found didn't support latin2 characters. Just finding an iconv, that runs on windows took 3 hours.

    5. Re:C++ needs something else ... by constpointertoconst · · Score: 1

      You should never have to use extern unless you are trying to interoperate with some external library.

      Regarding strings, you're right, UTF support was tricky (although if you don't know std::string is just a typedef of std::basic_string, so abstraction IS there, to a degree). C++0x improves the situation considerably (quoting wikipedia):

      There are three Unicode encodings that C++0x will support: UTF-8, UTF-16, and UTF-32. In addition to the previously noted changes to the definition of char, C++0x will add two new character types: char16_t and char32_t. These are designed to store UTF-16 and UTF-32 respectively."

      It also adds both UTF string literal syntax and user-defined literals.

      Regarding XML, I don't think it belongs in a "standard" library. Yes, it's common. It wasn't very common when the current C++ standard was introduced. But, it's a specific file format, not a general language/math/software feature. It might be "convenient", but there's something to be said for simplicity and keeping the standard library slim. It doesn't belong in the standard library any more than an image parsing library does. There are also many ways to write an XML parser, depending on what you are trying to optimize for (performance? memory? convenience?) That's pretty hard to "standardize".

      Similar things can be said regarding GUIs. They are inherently platform specific and thus fall outside the domain of a general purpose, relatively low level compiled language like C++, in my opinion. This is even more so something that everyone has wildly differing opinions on how to implement. There is no "correct" solution. There are GUI libraries with immense amount of work put into them, many of them for C++ and cross platform (e.g. Qt) and they change rapidly due to changing requirements. For all these reasons it makes sense to keep such a thing separate from the language.

      C++ is not supposed to be a convenient language. It's supposed to be a powerful, efficient language first and foremost. Convenience is nice, but when it interferes with the main goals, it takes a back seat in C++. This isn't necessarily a bad thing, it just depends on what your use case is. Do you want power, or convenience? (This is not to say that you can't write convenient constructs and libraries in C++, and C++0x makes that quite a bit easier still).

  45. Compiler Support by constpointertoconst · · Score: 1

    Nobody seems to have posted this useful reference yet:

    http://wiki.apache.org/stdcxx/C++0xCompilerSupport

    If anyone knows of a better one, please correct me.

  46. What about basic type sizes? by gr8_phk · · Score: 1

    I suppose defining the number of bits in types would be too much to ask? They give an example that uses an LL suffix for long long. I assume this means a 64bit integer. Would it be too much to define something like int16 or int_16? We have lots of code that uses typedefs to get these, and different projects sometimes define them differently. I know they'd argue that it breaks existing code - since people have already defined these types - but search and replace could be used. Perhaps they could provide a migration tool like Python did from 2.x to 3.0.

    1. Re:What about basic type sizes? by Arlet · · Score: 1

      Why ? There is already a standard header file for those types, and it works well enough.

    2. Re:What about basic type sizes? by David+Greene · · Score: 1

      Would it be too much to define something like int16 or int_16?

      #include <cstdint>

      --

    3. Re:What about basic type sizes? by shutdown+-p+now · · Score: 1

      Would it be too much to define something like int16 or int_16?

      No, it wouldn't. This has been there since C++ TR1 (5 years now):

      #include <cstdint>
      int32_t x = 123;
      int64_t y = 0xAAAAA107ll;

      Or are you asking why they didn't strictly define the built-in types such as "int"?

  47. C++ still not attractive to me by fyngyrz · · Score: 1

    Speaking ONLY for myself; I read the FA, and I still see no significant reason to move away from standard c.

    Know what would make me move? A syntax identical to the Python 2-series that compiled down to machine efficiencies similar to c. Now that's a beautiful syntax, a real step in the right direction. If I was writing it, I might be a little more strict about the indentation, so as to prevent things like lambda expressions, space/tab confusion, and single-line run-on, but overall, it's really, really nice as is. Add a good compiler and build in some portability, and I'd bite.

    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, generally at lower memory cost, higher speed, fewer "black boxes", and better portability. Which is not the same thing as saying there isn't anything unique to c++... just that the "good stuff" doesn't really add value I don't already have access to, albeit using much finer-grained techniques.

    Objective c is pretty much the same... I find that the whole idea of objc is highly overrated, most of the added features are time- and memory-adding crutches... just a thin layer added to c that pressures you to use a messaging model you could have easily implemented yourself if you needed it, which you likely wouldn't -- if OSX wasn't chock full of it. :^)

    On the Mac, I write an objc wrapper that talks to the OS, then write the core code in c. The only projects that I really write c++ for are those that arrive on my desk already written in c++, and which need my attention for porting, upgrades, etc. and even then... c++ methods end up wrapping c, generally speaking.

    From my perspective, c++ and objc are both solutions seeking non-existent problems; solutions with fairly heavy penalties and which create overcomplicated implementation paradigms that take the focus away from the problem at hand. Too much emphasis on making programming "easy" and not enough on making it good. When I have to put the details together, I have to care about them. 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. And I'm not just talking about code generation, although that's a problem too: I'm talking about managing the stack, making sure megabytes of cruft aren't glued to the application because some built-in capability incurs dependencies upon a whole series of frameworks or libraries, not having to fight the compiler-writers academic preconceptions about globals... I just prefer a finer degree of control, it suits me well.

    And... yeah, I'd write in assembly if I could, there's another whole layer of speed, size and related benefits to be had there, but the portability issues, even within the same OS, are just too troublesome unless the code is for a controller where I know the hardware isn't going to change. Now *those* are fun projects.

    --
    I've fallen off your lawn, and I can't get up.
    1. 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.

      --

    2. Re:C++ still not attractive to me by thePowerOfGrayskull · · Score: 1

      So to paraphrase, you'd use c++ if it were not c++?

    3. Re:C++ still not attractive to me by fyngyrz · · Score: 1

      I have no idea how you drew that conclusion. Certainly not from my Python remarks -- c++ syntax doesn't even vaguely resemble Python. Care to elaborate? Or just trolling?

      --
      I've fallen off your lawn, and I can't get up.
    4. 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.
    5. Re:C++ still not attractive to me by Anonymous Coward · · Score: 0

      You said you'd move from c to c++ if c++ was python 2. Retard.

    6. Re:C++ still not attractive to me by David+Greene · · Score: 1

      RAII is not important to me

      It's not? RAII is important to anyone concerned about resource use.

      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.

      So you do everything manually that RAII provides for free.

      I try really, really hard to never use other people's code for which I don't have control of the source.

      Code reuse is not valuable to you?

      Then I test the living heck out of things.

      As we all do.

      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.

      RAII is about more than just exceptions. RAII is about reasoning in the problem domain rather than in the swamp of details. It makes code simpler and clearer. It makes resource ownership and lifetime explicit. But even if it were just about exceptions, no amount of testing can guarantee that software will never fail. There must always be contingencies to handle failures. In the presence of exceptions, RAII helps manage that. But RAII is used for a lot more than exception safety.

      --

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

      --

    8. Re:C++ still not attractive to me by thePowerOfGrayskull · · Score: 1

      I have no idea how you drew that conclusion. Certainly not from my Python remarks -- c++ syntax doesn't even vaguely resemble Python. Care to elaborate? Or just trolling?

      Know what would make me move? A syntax identical to the Python 2-series that compiled down to machine efficiencies similar to c. Now that's a beautiful syntax, a real step in the right direction.

    9. Re:C++ still not attractive to me by ogl_codemonkey · · Score: 1

      A variable that is pushed to the stack make a register that can be used for something else. Yes, common architectures do often only have two or three registers available, once you take into account calling conventions that you aren't going to get around in any language as expressive as C or more so.

      Re-using registers is A Good Thing - it's not like you can make more of them.

      What makes you think a shift is more efficient than a divide? Are you taking into account the encoded instruction size, alignment, and variable decode latency? Instruction and jump caching?

      If you want to write assembly for everything you do, go for it - I kind of like being able to say "strlen(var);". I like "var.size();" a bit more - but it's your call if you wanna say "push edi; sub ecx, ecx; mov edi, [esp+8]; not ecx; sub al, al; cld; repne scasb; not ecx; pop edi; lea eax, [ecx-1]; ret"; or some variant thereof. Go for it. I'll be over here, writing features.

    10. Re:C++ still not attractive to me by Lord+Lode · · Score: 1

      C is very annoying to work with, for only two reasons as far as I'm concerned: no good strings, and no destructors. Especially the no destructors thing is annoying, as you need to do quite a lot of work cleaning things up manually depending on the code path. If in C you could just have some statement which says "when leaving this scope (break, return, end reached), do this (e.g. free something)", it's be a lot handier already.

  48. Re:Nice but... but nothing. They are useful. by David+Greene · · Score: 1

    Proper utilization of lambdas and closures pretty much make a lot of design patterns (template, strategy, visitor, for example) unnecessary in many contexts.

    I love lambdas but I don't have a lot of experience using them in large projects. I use the Visitor pattern a lot so I'm really curious to learn how lambdas can be used to avoid it. Can you post an example? Thanks!

    --

  49. Define constants for the bits to test by tepples · · Score: 1

    Read a byte, test the bits you want (with classic C style binary ands) and save the results in bitfield values.

    Without C-style enums, how would one define constants for the bits that one wants to test and then efficiently use those constants?

  50. C memory management is awful. by roguegramma · · Score: 1

    C++ still is C compatible.

    C garbage collection is awful because double deallocation for example does not cause an immediate error, but can produce an error much later.

    Of course you can try to work around that using debug allocation libraries, which make your program run 0.01 as fast, and which probably are not the first idea of a newcomer to the language.

    Of maybe 4 a bit larger C++ projects I had, 3 had major problems which might have been related to this behaviour, and I was able to solve the issue only in my last project out of these 3.

    --
    Hey don't blame me, IANAB
  51. Re:Nice but... but nothing. They are useful. by radtea · · Score: 1

    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.

    And you save even more typing because the damned things are almost impossible to comment properly.

    I'm being a bit facetious, as I think any industrial-strength programming language ought to have lambdas, but I think they are far more useful to library and algorithm developers than application developers. I've been on both sides of that divide, and while I grant lambdas are useful and elegant, I've also seen them used in entirely inappropriate ways by application developers that have made their work hard to understand and even more difficult to debug.

    For example, while g++ mostly supports the new standard I'm pretty sure gdb doesn't allow you to set a breakpoint in an anonymous function. Until it does I would say they have no place in application development, or only under the most draconian coding standards that prevent the kind of unpleasantness you get when a junior developer realizes all the kewl stuff they can do with them.

    --
    Blasphemy is a human right. Blasphemophobia kills.
  52. Re:Nice but... but nothing. They are useful. by gknoy · · Score: 1

    Does naming them verbosely, and having similarly verbose names of parameters, help? Sometimes I get annoyed by that in Lisp and its variants, but that plus a block comment illustrating its purpose seems like it ought to be sufficient. Am I missing something in what you were looking for?

  53. Summary by Anonymous Coward · · Score: 0

    Still no garbage collector.
    Lambda's are written like: [&varInScopeYouWantToUseInside](arglist)->returnType { statements }
    (If you think this looks confusing, atrocious and quite unlike any other lambda for no apparent reason, you just have to suck it up and accept that C++ has entered the Century of the Fruitbat.)
    Type inference: auto varToDeclare = expression //where expression's type can be figured out compile-time.
    Finally. I love this, and if you're like me tired of writing "complicatedClassName x = new complicatedClassName;" you will love it too.
    Since the designers were afraid that people would get confused between "classN var(constructorArgs);" and "structN var = {initer};" they've decided to add "classN var {constructorArgs};". This made me check whether it was April 1st, but no. Be prepared for "Ctor(args) : member { memberArgs } { statements }"
    Often in C++ you find yourself forced to declare a constructor like "Ctor(){}". But now you are allowed to say "Ctor()=default" which is, as any fool can plainly see, clearly more efficient and relieves the programmer of this heavy burden. Works for destructors as well. In addition, you can now delete functions with "func()=delete". Now you only need to delete operator= and the copy constructor to make your objects uncopyable.
    Because NULL isn't typesafe (except on systems on which it is) nullptr was added. Why they couldn't simply require NULL to be typesafe is beyond me, but I suppose that's only one #define away.
    Constructors can now delegate to another constructor in the same class with Ctor() : Ctor(args) { statement }
    Rvalue references are now available, declared with two && instead of one &. Since an rvalue is temporary this can save you from unnecessary object copying. Suppose you have "lval1 = lval2" - then a copy must be made from all the data in lval2 since this has copy-by-value semantics and lval2 could be referenced later on. But in the case of "lval = rval" rval is inaccessible so if it refers to its data by a pointer, you can just move the pointer to lval.

    The runtime library.
    Launching threads now works as in other languages (hype about operator() is just that, since interally those are just functions too of course). You can wait for them to finish with .join() or leave them alone with .detach() (which is called by their dtor). Mutexes and other data protection objects have now been standardised.
    shared_ptr is a refcounting pointer type. VB had this in the early nineties, but better late than never. Note that if you use these with objects that do their own refcounting, this can be either more efficient (since it potentially saves a virtual function call) or less (since you'll have to effectively keep two reference counts). And they cannot be shared with anything other than C++ at the moment. unique_ptr doesn't keep a refcount but instead tries its best (compile-time) to keep you from obtaining two references by accident.
    Given a set [a, b> (where a and b are references to the beginning and the just-beyond-the-end of the set, like "int a[10]; b = a + 10") you can now ask all_of(a, b, lambdaPredicate), any_of( ditto ) or none_of( ditto), which all return a boolean value as you'd expect. copy_n(source, elements, destination) does what you think it does and is hopefully simpler and hence safer than past constructs. You can now quickly fill an array a[10] with integers using iota(a, a + 10, 1). It's a shame that these all have to use C-ish syntax, instead of a cleaner object-based syntax, but I suppose you cannot have everything since C++ doesn't support extension methods. (At least not with normal syntax. It is common in libraries to use | for this but even though the C++ committee generally doesn't shy away from chtulhuesque syntax, this was clearly a bridge too far.)

    If these changes seem somewhat underwhelming, I'd recommend you don't read the last paragraph of the article.

  54. Re:Nice but... but nothing. They are useful. by WWE-TicK · · Score: 1

    For example, while g++ mostly supports the new standard I'm pretty sure gdb doesn't allow you to set a breakpoint in an anonymous function. Until it does I would say they have no place in application development, or only under the most draconian coding standards that prevent the kind of unpleasantness you get when a junior developer realizes all the kewl stuff they can do with them.

    VC2010's debugger allows breakpoints in lambdas. Just sayin' ...

  55. 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 ?
  56. Re:Nice but... but nothing. They are useful. by luis_a_espinal · · Score: 1

    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.

    And you save even more typing because the damned things are almost impossible to comment properly.

    I'm being a bit facetious, as I think any industrial-strength programming language ought to have lambdas, but I think they are far more useful to library and algorithm developers than application developers.

    I disagree. One of the last projects I worked with (Java, not C++, however) we had to pass n anonymous "transformer" objects that would operate on data pulled from a database, n and the actual transformations dependent on particular conditions. For all cases where n > 1 this was hideous as we did not have lambdas in the 1.5/1.6 version of the language. Everything else in the application worked and looked wonderfully except where we have to create/add anonymous "transformers". Lambdas would have been extremely useful here, in application development.

    Other examples have been with common exception handlers (which without lambdas, is incredibly hideous) or event listeners in GUI development. With other JVM languages that support lambdas (say, Groovy or Mirah), this type of library and application development work is trivial and elegant (ergo, less prone to bugs.)

    Same applies to any language that does not support lambdas. Once you have them, anywhere where you have to structure your class hierarchy to include composition with the purpose of refining/extending pieces of an algorithm, that's a possible (possible, not certain) candidate for being replaced with a lambda.

    I've been on both sides of that divide, and while I grant lambdas are useful and elegant, I've also seen them used in entirely inappropriate ways by application developers that have made their work hard to understand and even more difficult to debug.

    For example, while g++ mostly supports the new standard I'm pretty sure gdb doesn't allow you to set a breakpoint in an anonymous function. Until it does I would say they have no place in application development, or only under the most draconian coding standards that prevent the kind of unpleasantness you get when a junior developer realizes all the kewl stuff they can do with them.

    Hmmm, but that argument can be made with any other programming language construct or syntactic sugar in any programming language and in any context. Everything is open to abuse by the inexperienced or incompetent. There is a valid assumption about the level of competency that one must expect from developers. If they fail at that (and create abominations with a programming language, or a programming language feature), that's more a failure on the developers than on the design of the language.

    Case in point, Gosling is still adamant about removing operator overloading from Java because "it's dangerous". And that is a stupid thing to say. Really, it really is. Yes, it can be open to abuse. But then again, that's why, in Java, we have to do this abomination:

    // assume a, b and c and d are BigDecimal, do d = a^2 + 2*b + c; d = (a.pow(2)).add( b.multiply(2) ).add( c );

  57. Re:Nice but... but nothing. They are useful. by luis_a_espinal · · Score: 1

    Proper utilization of lambdas and closures pretty much make a lot of design patterns (template, strategy, visitor, for example) unnecessary in many contexts.

    I love lambdas but I don't have a lot of experience using them in large projects. I use the Visitor pattern a lot so I'm really curious to learn how lambdas can be used to avoid it. Can you post an example? Thanks!

    Every replacement has to be done in a case by case basis. Not all instances of those patterns can be replaced with lambdas.

    Using the visitor sample from here, one could do the following (trivial example, I know):

    class ConcreteVisitorB extends AElement{
    void VisitConcreteElementA(ConcreteElementA & a ){ a.operationA(); }
    }

    class ConcreteElementA extends AElement {
    public void accept(AVisitor v) {
    v.VisitConcreteElementA(this);
    }

    public void operationA() {
    // an atomic, intrinsic opertion on ConcreteElementA objects.
    }
    }

    can be replaced with this:

    auto lambdaA = [](ConcreteElementA & v ){ v.operationA(); }
    auto donothing = [](AElement & v) { /* yo! nothing here */ }

    class ConcreteElementA extends AElement {
    public void accept( [](AElement & v ) {
    v(this);
    }

    public void operationA() {
    // an atomic, intrinsic opertion on ConcreteElementA objects.
    }
    }

    Obviously this is a trivial example. For real-world examples, one has to make an engineering decision of whether to replace a particular pattern or composition construct with a lambda, depending on a lot more factors than just coding aesthetics.

  58. Re:Nice but... but nothing. They are useful. by David+Greene · · Score: 1

    But that's not really replacing the Visitor pattern, is it? There is no double-dispatch in the lambda example. Thus I can't pass around a Visitor object and invoke it on arbitrary objects. I must pass around a concrete lambda. This is certainly useful in some cases but what it's really replacing is a struct of operations, not a full-blown Visitor.

    Still, thanks for the example!

    --