Become a fan of Slashdot on Facebook

 



Forgot your password?
typodupeerror
×
Programming Upgrades

Bjarne Stroustrup Announces the C++ Core Guidelines 262

alphabetsoup writes: At CppCon this year, Bjarne Stroustrup announced the C++ Core Guidelines. The guidelines are designed to help programmers write safe-by-default C++ with no run-time overhead. Compilers will statically check the code to ensure no violations. A library is available now, with a static checking tool to follow in October.

Here is the video of the talk, and here are the slides.The guidelines themselves are here.
This discussion has been archived. No new comments can be posted.

Bjarne Stroustrup Announces the C++ Core Guidelines

Comments Filter:
  • Wait what? (Score:5, Funny)

    by Virtucon ( 127420 ) on Thursday September 24, 2015 @09:07AM (#50588749)

    If you take all the fun out of finding memory leaks and stack overflows what fun is there to C/C++? I mean I just love using AutoPtr everywhere, it's perfect!

    • by tepples ( 727027 )

      If you take the drudgery out of finding stack overflows, then perhaps you'll have more time to d%%% around on //||] stackoverflow.com.

    • by Godai ( 104143 ) *

      It's the GSL -- Guideline Support Library. It's header-only, nothing to link against, and it's being kept small to make it easy for it to be cleared for use.

  • by beelsebob ( 529313 ) on Thursday September 24, 2015 @09:13AM (#50588775)

    For example, one of the guidelines here is to always prefer make_shared over std::shared_ptr(new ...). That's good advice for a couple of reasons
    1) it allocates your memory for the shared_ptr control block and the object contiguously
    2) it means you can't separate the allocation from the creation of the shared ptr and end up with an owner who's not looking at the shared ptr in-between.

    However, it also means that if you have any weak_ptrs pointing at the end of that shared_ptr, the object itself won't go away until all the weak_ptrs do too (because the control structure won't go away until they do, and they're contiguously allocated).

    • However, it also means that if you have any weak_ptrs pointing at the end of that shared_ptr, the object itself won't go away until all the weak_ptrs do too (because the control structure won't go away until they do, and they're contiguously allocated).

      Shouldn't you lock the weak_ptr before using it?

    • Just like "don't use goto", or "don't use threads", etc., these guidelines and recommendations are really great to prevent beginners from making hard to spot errors, but all those variations and features exist for a reason and have a use.
      • by 140Mandak262Jamuna ( 970587 ) on Thursday September 24, 2015 @10:38AM (#50589277) Journal

        Just like "don't use goto", or "don't use threads", etc., these guidelines and recommendations are really great to prevent beginners from making hard to spot errors, but all those variations and features exist for a reason and have a use.

        Nobody uses GOTO anymore. With event driven programming and call back functions, it all spaghetti code strewn with COME FROM statements, effectively.

        • by Bengie ( 1121981 )
          I've ran into situations where not using GOTO resulted in much messier code that was harder to read. This rarely happens, but it does happen, and I always take a step back and try to find a better way than using GOTO.
        • by Darinbob ( 1142669 ) on Thursday September 24, 2015 @05:40PM (#50592475)

          I use goto. Sometimes. When you're in C then it's can be effective way to do a function clean up before exiting. Sure this can be over done but trying to avoid a goto like a religious taboo can also result in some pretty nasty code to replace it.

          • For C that's a perfectly reasonable use of goto. For C++ you should use unique_ptr or wrap your resource in your own object that you can stack allocate. RAII is a very nice pattern in C++.
            • RAII is not a "pattern" it is an "idiom".

              A pattern is independent from programming languages, idioms are thins you only can do in one/some language.

              e.g. using pointers and ++ to copy a \0 terminated string like this:

              strcpy(char* dest, char* src) {
              while (*dest++ = *src++)
              ;
              }

              is an idiom ... supported by certain languages, not a pattern.

              • by Darinbob ( 1142669 ) on Thursday September 24, 2015 @10:18PM (#50593989)

                I hate patterns. They're too much like verses from a religious text, because I've run across people who seem unable to understand your code unless it uses patterns from the official pattern Bible. Holding a conversation with them can involve being interrupted every few minutes with "oh, that's a FurblingFunctorFactory, why didn't you say so?" If you don't keep a close watch they'll go and changing existing/working code to rename classes to indicate what pattern they are.

            • For C that's a perfectly reasonable use of goto. For C++ you should use unique_ptr or wrap your resource in your own object that you can stack allocate. RAII is a very nice pattern in C++.

              So unique_ptr will close open file handles and network connections?

    • It also helps exception safety. A call like Foo(new Bar, new Bar) can allocate one Bar and throw on the next, creating a leak. Putting them into shared pointers in the call doesn't work, since shared_ptr(new Bar) is not a function, and so the compiler is justified in doing both allocates and then putting each pointer into a shared_ptr. make_shared() is a function, and must be executed as a unit, so that enforces the order of allocate, make_shared, allocate, make_shared. No memory leaks there.

    • by D.McG. ( 3986101 )
      There's a much easier way to accomplish this: use reference counted objects, rather than smart pointer templates around dumb objects.

      Define IRefCount to include AddRef (or Retain) and Release methods. Make all interfaces extend IRefCount. Define CRefCount to include a FinalRelease method; which by default calls "delete this", and will be invoked when the reference count reaches zero. This method can be overridden to return objects to pools, be handled by some other deallocator, etc.

      This removes the n
      • We're still going to need two objects, one a base object and one a pointer object. If we use raw pointers, the reference count will not be incremented and decremented properly, and we need the reference count to reliably be equal to the number of pointers extant. Therefore, the pointer needs to have its own copy constructor, copy assignment operator, and destructor, which will call the appropriate increment and decrement methods (the decrement method to include the deletion as a special case). If we kee

        • by D.McG. ( 3986101 )
          I only brought this up as an alternative to yet-another redefinition of shared_ptr. We don't need new libraries to have shared objects.

          If you're looking for the lazy approach, then yes, the smart pointer object can be used to call AddRef / Release for you. Or you could just call these methods yourself and call it a day, like we did in Objective-C for years until ARC came around. The smart pointer object in this design is optional.

          I think you missed the point with the pointer object. There is no re
        • by spitzak ( 4019 )

          We're still going to need two objects, one a base object and one a pointer object. If we use raw pointers, the reference count will not be incremented and decremented properly, and we need the reference count to reliably be equal to the number of pointers extant. Therefore, the pointer needs to have its own copy constructor, copy assignment operator, and destructor, which will call the appropriate increment and decrement methods (the decrement method to include the deletion as a special case). If we keep the reference count with the object instead of with the pointer, we can keep the pointer size down without indirection.

          This is no more complicated than what has to be done with shared_ptr. And you are confused, you can use raw pointers all you want, as long as you know there is a shared_ptr pointing at the object. This happens in many cases.

          We need to document heavily that IRefCount (or something more according to C++ naming) is to be inherited virtually, as otherwise we could have more than one reference count if we add it to multiple levels of a class hierarchy. (C++ multiple inheritance can be tricky to get right.)

          So, we've got the pointer object, which will contain the pointer and have some attached functionality, and the reference count mixin. This works as long as we can easily modify the class structure, but it does require a fairly sophistication serialization/deserialization system to keep the modified and unmodified objects in sync. In addition, since it changes the memory layout of a class, it can lead to slow compiles.

          It's not a "mixin". It is a base class. This avoids your supposed problems.

          With this, we also don't get weak_ptr functionality. A shared_ptr object has a shared pointer count and a weak pointer count. This makes it possible, for example, to have a circular list that can be destructed: have one link be a weak_ptr and everything else a shared_ptr. The object itself is destructed when the shared pointer count goes to zero, and the shared_ptr object when both go to zero. (A weak_ptr does nothing on its own, but can be converted to a shared_ptr if the target object is still there.)

          You can implement weak_ptr in EXACTLY the same way make_shared does it. The object is destroyed but the memory is not freed until the weak_ptr count goes to zero. In fact it is fairly easy to have "an object that

          • One difficulty with raw pointers in this case is that you have to know what's an owning raw pointer and what's a non-owning raw pointer. As far as not using an object and maintaining the reference count by hand, you're going to screw up sometime, and that's going to be a difficult error to find. In C++, I know that a unique_ptr reflects ownership, a shared_ptr reflects shared ownership, it's a good convention to say raw pointers do not own, and that shared_ptr won't mess the reference count up.

            I don't

  • News at eleven (Score:3, Informative)

    by Anonymous Coward on Thursday September 24, 2015 @09:13AM (#50588777)

    Imperative programmers reinvent functional programming concepts, but in a shitty way. More at eleven.

    • Re: (Score:2, Troll)

      When functional languages can do real world high speed low latency application development that rivals c++ for performance, then I'll consider giving up c++. Until then, we'll re-invent your shitty programming concepts in a way that is performant.

  • by Carewolf ( 581105 ) on Thursday September 24, 2015 @09:41AM (#50588935) Homepage

    He has a connecting to all the features he put into C++ and any coding guidelines should include thing that should not be used. First among those are exceptions, unfortunately Bjarne has never wanted to admit C++ exceptions were a mistake.

    • Bjarne has never wanted to admit C++ exceptions were a mistake.

      What should a method that fails do instead of returning an exception? Should it instead be set up to explicitly return two different types of return value, namely the object that it's supposed to return if it exceeds or an object describing the failure if it fails?

      • Comment removed based on user account deletion
        • 1) There's a distinction between checked (compile-time) and unchecked (runtime) exceptions. All C++ exceptions are unchecked.

          I agree with that. Exceptions are entirelt typed at runtime which is not very C++ish. I don't really feel all that happy about thar in C++.

          4) try/catch blocks also have a "finally" clause that is guaranteed to be run after the try/catch blocks complete, regardless of whether either one of them runs to completion or throws an exception out of the method. This is crucial for safely cle

          • I too lament the way C++ does exceptions versus how Java handles then. That said, you bring a good point. I've seen new guys in the shop coming from a Java background struggling to completely wrap their heads around RAII. Finally in Java is the typical source for the struggle.
        • by 0123456 ( 636235 )

          And this is why it often seems that 90% of the Java code I read is catching exceptions and doing stuff with them. Normally throwing another exception.

          • by lgw ( 121541 )

            And this is why it often seems that 90% of the Java code I read is catching exceptions and doing stuff with them. Normally throwing another exception.

            Ahh, Pokemon code! Gotta catch em all!

            If you can actually find the program logic hiding in all the Java boilerplate, you're doing Java wrong: moar boilerplate!

        • by tepples ( 727027 ) <tepplesNO@SPAMgmail.com> on Thursday September 24, 2015 @11:17AM (#50589597) Homepage Journal

          Every object that can be thrown/caught must implement the Throwable interface

          Then have all exceptions extend a subclass of std::exception [stackoverflow.com]. The guidelines mention use of a subclass [github.com] as opposed to using the built-in exceptions directly.

          the C++ alternative is only allocating objects on the stack and implementing destructors that clean up their resources

          Also called Resource Acquisition Is Initialization (RAII), or "automatic resource destruction" if you don't want to remind readers of the record industry (RIAA).

          but then you have the restriction of not being able to allocate on the heap

          You can take advantage of automatic resource destruction if you wrap your object on the heap in a smart pointer type (std::unique_ptr or std::shared_ptr as appropriate) on the stack. If that isn't appropriate in a given situation, C++11 supports a scope guard idiom using std::shared_ptr and lambda expressions. The finally factory described in the Guidelines [github.com] is ultimately an update of a method described in a 2000 article by Andrei Alexandrescu in Dr. Dobb's [drdobbs.com].

        • C++98 did have the "throw" function specification, and in general it was found to be more trouble than it was worth, with the possible exception of "throw()", which should be replaced by "noexcept" in modern C++.

          "finally" does not exist in C++, fortunately, since RAII is much better. There's no reason you can't allocate on the heap and have destructors clean everything up. That's what auto_ptr was for in C++98 and what shared_ptr and unique_ptr are for in C++11. If you need to worry about what the des

          • by spitzak ( 4019 )

            C++98 did have the "throw" function specification, and in general it was found to be more trouble than it was worth, with the possible exception of "throw()", which should be replaced by "noexcept" in modern C++.

            Apparently it was Visual C++ that made "throw()" do what "noexcept" now does: it means you can be certain that this code will not throw an exception. This caused it to be used a lot, but the actual C++ definition of what "throw()" did was not that at all and was quite useless.

            "finally" does not exist in C++, fortunately, since RAII is much better. There's no reason you can't allocate on the heap and have destructors clean everything up. That's what auto_ptr was for in C++98 and what shared_ptr and unique_ptr are for in C++11. If you need to worry about what the destructors are doing and what order they're called in, you're almost always doing it wrong. (There may be applications I am currently unfamiliar with where that matters, but that would be unfortunate.) A "finally" block has low cohesion and high coupling, whereas destructors have high cohesion and low coupling.

            You are correct that RAII can do everything "finally" does, but it does sometimes require the writing of very strange classes when some kind of finally statement would work better. But to actually work well the statement can't be at th

    • He has a connecting to all the features he put into C++ and any coding guidelines should include thing that should not be used. First among those are exceptions, unfortunately Bjarne has never wanted to admit C++ exceptions were a mistake.

      That's a hard call. Exceptions have their place. The thing I cannot stomach is the catch(...) construct. I understand the technical reasons for having it. I still think that was a bad design decision that outweighs the pros. It is almost always impossible to quickly pinpoint the origin of the error (specially if you do not have a core dumb to at least analyze.)

  • by fragMasterFlash ( 989911 ) on Thursday September 24, 2015 @09:59AM (#50589015)
    Its nice to see efforts to drive the complexity out of the design/implementation of safe code but this won't due much to improve the already error prone task of debugging optimized code. You don't always have the luxury of running a debug build, especially when analyzing a crash dump from a customer and templated/STL C++ constructs are often too complex for debuggers to parse properly. Hopefully these efforts reduce the number of crashes enough to justify the added complexity of debugging the crashes that still occur.
  • Ada had this in 1995 (Score:4, Informative)

    by david.emery ( 127135 ) on Thursday September 24, 2015 @10:10AM (#50589061)

    Ada95 added OO features including clear mechanisms (enforced by the compiler) on how to get OO design benefits without runtime performance costs or risks for dispatching.

    Much of what I've seen in C++ is a response to problems in the original language design, particularly gaps or errors of omission.

    Computer Science in the 21st Century seems to be full of stuff we knew about in the '80s and '90s, but forgot.

    • Yo mama!

    • What part of C++ OO imposes runtime performance costs? Virtual functions are one indirect access of a table that's likely to be in cache already. What are the risks in dispatching?

      Modern C++ is a successful attempt to make C++ into a much better language. You could call that a response to earlier problems, but it's not just a bunch of patches.

      Computer programming in the 21st Century seems to have problems with stuff we knew about in the 70s. Java's "finally"? Who thought that was a good idea?

      • > What part of C++ OO imposes runtime performance costs?

        Uh, the fact that it is designed for the uncommon single case instead of the common multi case. You want to optimize for the throughput, not latency.

        OOP (Object Orientated Programming) has terrible performance scalability since it has terrible D$ (Data Cache) usage. For high performance OOP is completely ditched in favor of DOD (Data Orientated Design). DOD is used heavily in modern game development, and HFT (High Frequency Trading.)

        I would recomm

        • Serious question......
          Game programmers often use C++ (for various reasons). Since you are a game programmer who doesn't like C++,
          What do you typically use to write programs?
          • > Game programmers often use C++ (for various reasons).

            Performance is the #1 of reason, but yeah, C++ gets the right balance of power, compactness, performance, and multi-paradigm design which builds upon C's foundation.

            > What do you typically use to write programs?

            Just because I'm vocal, and passionate, doesn't mean I toss the baby out with the bath water.

            I would be stupid to ignore the wisdom of Bjarne Stroustrup: [stroustrup.com]

            There are only two kinds of languages:

            * the ones people complain about and
            * the ones n

    • C++ grew somewhat organically out of C. C is (IMHO) an excellent language, but its goals often differ from C++'s goals.

      I won't argue with your conclusion; it's true. But a lot of what was achieved in the research and design of the '80s and '90s was achieved by burning down the software stack and starting over. (Take Smalltalk for example.) People are rediscovering those things in a context where the existing stack matters and tackling the hard work of reconciling those developments with what we already

      • And that's what makes Ada95 (and subsequent versions) so interesting from a language design perspective. Ada95 built on the Ada83 language (which itself built on Pascal, as well as CLU and other research languages), adding OOP (including supporting concurrent objects in a way that I haven't seen in other "modern" programming languages in this era of multi-core processors). There are design trade-offs, and these are well-documented. If you're interested in such things, the published design team rationale

    • by phantomfive ( 622387 ) on Thursday September 24, 2015 @02:58PM (#50591245) Journal
      It reminds me of this quote: [c2.com]

      "It's quite apparent that the evolution of the C family of languages (C, C++, Java, C#) is converging on a language very like Ada, except unfortunately as a kludgepile rather than a clean design."

  • Sad, really (Score:5, Insightful)

    by jandersen ( 462034 ) on Thursday September 24, 2015 @10:27AM (#50589175)

    I think it is sad, looking around on the responses so far, to see, yet again, that the overwhelming response to this is to jeer at anything that is beyond people's comprehension. I guess what it boils down to is, that far too many who call themselves coders can't be bothered to sit down and work out a detailed plan before barging ahead. You get nothing but trouble from OOP if you think in terms of simple scripts, and that is particularly true of C++.

    • Re:Sad, really (Score:5, Insightful)

      by myrdos2 ( 989497 ) on Thursday September 24, 2015 @12:10PM (#50590021)

      In short, I suggest that the programmer should continue to understand what he is doing, that his growing product remains firmly within his intellectual grip. It is my sad experience that this suggestion is repulsive to the average experienced programmer, who clearly derives a major part of his professional excitement from not quite understanding what he is doing. In this streamlined age, one of our most undernourished psychological needs is the craving for Black Magic and apparently the automatic computer can satisfy this need for the professional software engineer, who is secretly enthralled by the gigantic risks he takes in his daring irresponsibility. For his frustrations I have no remedy......

      -- Edsger W. Dijkstra

      I love this quote, and I say that as a C++ programmer. It falls in with my own philosophy, which is that the more complicated something is, the less likely people will get it right. And C++ is extremely complicated. It's not the OO design that necessarily trips people up, it's the sheer amount of minutiae you need to remember and the care you must take not to do something stupid.

    • My impression of earlier versions of C++ was that it was a great language to lay formal siege to a problem, but not nearly as good for less formal approaches. Modern C++ has improved the siege engines, and become a lot more mobile.

    • that far too many who call themselves coders can't be bothered to sit down and work out a detailed plan before barging ahead.

      That's a good description of the C++ design process, and why the "approved" way of using the language is completely different than the "approved" way of not long ago.

      How many ways are there to allocate memory in C++? I'm starting to lose count.

  • "Within C++ is a smaller, simpler, safer language struggling to get out." -- Bjarne Stroustrup

    Very true, C++ would struggle no matter how laudable the goal is.

  • More than half of Stroustrup's talk was concerned with pointers. In 2015, we still need the kind of effort Stroustrup is calling for, simply because a fairly advanced OO language STILL uses pointers, with the risk of dangling ones, of pointers outliving the thing they point to, etc. etc. ? I dunno, people... but this is one of the main reasons I never made the switch to C++.
    • Unless you're dealing with hardware directly, you don't need pointers at all.
      • by Xtifr ( 1323 )

        Tell that to all the C libraries I link to from C++ programs.

        Until someone is motivated to create C++ wrappers for every C library I might possibly want to use, I don't see any way to get away from some use of pointers. And so, until that mythical day, I think having some guidelines for pointer use in C++ is a good thing. Especially if the first one is:don't use raw pointers if there's any reasonable alternative. :)

        (Of course, I could limit myself to languages where you cannot use a C library until someone

BLISS is ignorance.

Working...