Slashdot Mirror


Design by Contract in C++?

An anonymous reader asks: "I have read some of the stuff on Eiffel, watched their tutorial videos about design by contract, and the entire thing sounds like a pretty good idea. However, the problem is that we don't use Eiffel at work, and I highly doubt I could get people to come around to the idea of switching to it. Although we use a lot of C++, I can imagine that a lot of the ideas from Eiffel can be applied there. I have looked around on the net and found a few articles talking about different ways of applying design by contract using assert statements and the like. I also found the dlib C++ library on SourceForge which, among other things, puts a design by contract face on a lot of API calls. So, there are obviously people doing it. What is everyone's experience with Design by Contract in C++? What tools are there that help make it a workable system? Lastly, are there any pitfalls to taking this approach in C++?"

24 of 114 comments (clear)

  1. In C++ by revlayle · · Score: 2, Funny

    I call that "using interfaces" and "strict polymorphism" (and "bunnies"!!!)

    1. Re:In C++ by bheilig · · Score: 5, Insightful

      Here are some pitfalls you might run into:

      1. Real DBC inherits the contracts from ancestor versions. Preconditions are or-ed together and postconditions are anded together. Invariants are also anded together. If you just use assertions you won't get this.

      2. Eiffel allows you to disable the run-time execution of contracts at a fine level of detail. Again, if you use assertions you can only enable all or disable all.

      3. There is no 'old' keyword in C++. Therefore you can't use 'old' in assertions.

      4. According to DBC, a routine is in a transitional state during the execution of a routine. What happens if a routine calls another routine in the same class? Should it check the invariant? The answer is no. There are other cases as well.

      5. It's difficult to implement a loop variant with an assertion. Not a big deal since most Eiffel code I've seen doesn't use loop variants.

      If you don't want to use assertions, you can try some of the class pre-processors that are out there. You will see mixed results. In particular, I don't know of one that can handle 4. This is a show stopper.

      I think you only have two choices. Use Eiffel or don't use contracts.

      Brian

    2. Re:In C++ by Coryoth · · Score: 4, Insightful

      Besides the many very good points you mention there's also the question of documentation - good DbC systems are integrated into the autogenerated documentation elegantly. All that said, you do have more options then Eiffel if you want to use contracts. If you use Java you can use JML which I believe covers all your points, and my point about documentation. If you use Ada you can use SPARK which again, covers your points quite well. Both SPARK and JML also offer (via ESC/Java2 for JML) extended static checking as well as the usual runtime checking of contracts. Finally for C# there's Spec#, but I don't know too much about that one.

      Still, Eiffel is actually an extremely elegant language with powerful DbC built into at the core. If DbC is something that's important to you Eiffel probably is your best choice.

  2. I don't understand the question... by Anonymous Coward · · Score: 4, Funny

    ...but I'm sure Java + XML is the answer.

    1. Re:I don't understand the question... by WilliamSChips · · Score: 3, Funny

      Anything is a better answer than C++ for anything. Except maybe COBOL and shell script.

      --
      Please, for the good of Humanity, vote Obama.
    2. Re:I don't understand the question... by WilliamSChips · · Score: 2, Funny

      I deliberately did that. Perl isn't a programming language, it's a natural language that is somehow parsed by the compiler

      --
      Please, for the good of Humanity, vote Obama.
    3. Re:I don't understand the question... by Haeleth · · Score: 5, Funny

      Perl isn't a programming language, it's a natural language that is somehow parsed by the compiler

      I must strongly object to your use of the term "natural" in that statement.

    4. Re:I don't understand the question... by EsbenMoseHansen · · Score: 3, Interesting

      Strange. After trying dozens of languages, I still return to C++, and I still think it is my favorite strongly typed language (yeah, I know, nobody can agree on strongly typed, but you know what I mean).

      For loosely typed, I'm more torn. Ruby is nice, so is Perl. Python seems a bit limited to me, and the indention thing is just braindead, but maybe that is just a matter of adjustment. I haven't tried Scheme or that functional language that is so popular these days, but I will get around to it.

      I do have 3 gripes with C++: No closures, no closures and no closures. Oh yeah, a way to statically initialize arbitrary objects would be nice. I have seen few other valid complaints with it, but lots of silly ones.

      For the worst language I have tried yet, I nominate PL/I. For the worst that anybody still uses for new projects, Java, especially it's "let's throw all our type info away" implementation of templates, sorry, generics. And no closures there either. Horrible language.

      For best assembler, I nominate C.

      As for the question, doing real design by contract would require a pre-processor or manual insertion of suitable code in the beginning and end for every function. Neither is exactly pretty, but I believe lots of other languages do it this way. Personally, I think that excessive preconditions is a sign of poor OO design, but testing invariants do make sense for certain cases. Postconditions are better handled with an ordinary testframework.

      And remember that lots of ideas looks awsome on paper, and turns out to be more bother than they are worth in real life.

      --
      Religion is regarded by the common people as true, by the wise as false, and by rulers as useful.
  3. Must Buy New Book For Latest Proggramming Fad! by __aaclcg7560 · · Score: 3, Informative

    It must be a conspiracy with the technical publishers to keep coming up with new technology fads to create a demand for new editions of old books. I stopped buying doorstoppers years ago because of this.

    1. Re:Must Buy New Book For Latest Proggramming Fad! by Anonymous Coward · · Score: 2, Insightful

      You know, not _every_ programming design method or management method is necessarily a "fad". Some of these things are popular because they are useful.

      For what it's worth, design by contract is *very* useful when you are writing software for things that absolutely need to work, guaranteed (eg; medical, aviation, energy, etc). Eiffel is so good at this particular way of describing software that it literally changes how you think about programs.

      Maybe you should take a look at it before going off about conspiracies..

    2. Re:Must Buy New Book For Latest Proggramming Fad! by Molt · · Score: 2, Interesting

      For that one example, pretty much. Now try and write me a C++ class function for an employee which is allowed to change the employees details, but not those of their direct manager.. whilst other functions on the employee should be able to. Show me how I can guarantee that an attribute is never decreased in any method, whilst allowing increases quite happily.

      --
      404 Not Found: No such file or resource as '.sig'
  4. Verbal Contracts by dch24 · · Score: 4, Interesting

    In the development environment I work in, we use entirely C++, and combine embedded Linux, desktop Linux, and several server OSes. There are six engineers working on my part of the project (the embedded part), and a similar number working on the other parts.

    Although we have enough freedom to switch over to a Design By Contract if we all agree to do it, we currently use documentation as a semi-formal contract, starting with design meetings where we verbally define the contract, which we write up piecemeal as we implement sections of code. Obviously, when multiple companies are collaborating on a business system, Design By Contract may be necessary to nail down the project requirements for each participating company. But in-house, what are the advantages of a formalized system over verbal, face-to-face communication? Wouldn't the meetings be held and the documentation be written anyway? As the project evolves, design changes can be implemented in an organized way, but again, the formal definitions would be redundant with the design change meetings.

    1. Re:Verbal Contracts by eln · · Score: 2, Funny

      If you make the contract long and detailed enough, it provides something to beat coders with when they violate the contract.

    2. Re:Verbal Contracts by NovaX · · Score: 2, Interesting

      What you're thinking of is more on the lines of a UML as blueprint vs. UML as sketch. DBC is purely code-level and is simply a good practice. Good programmers will at least check all preconditions (e.g. if (param == null) {throw new IllegalArgumentException("Param=NULL")}). That's step one of the DBC philosophy. Having the whole process built into the language simply makes it cleaner reduces LOC.

      Design by Contract basically means that someone takes the responcibility to make sure inputs and outputs are valid. A verbal contract is loose - everyone assumes that everyone else did the right thing and the data is valid. When someone makes a coding mistake, such as passing in a null object, it may propogate pretty far and cause an error to appear. You'll then spend a lot of cycles trying to fix the problem and work your way back to the real offender. So DBC simply forces an error to happen right away and saves time.

      So think of DBC as your friend. It never gets in the way of refactoring, yet kindly points out problems before your customers do. :)

      --

      "Open Source?" - Press any key to continue
  5. Simple Solution - Violence by Anonymous Coward · · Score: 5, Funny

    I place a one line comment above each of my C++ functions that I want to have Eiffel like design by contract features:

    - // Note: If you don't pass reasonable values to this function I will fucking kill you
    -
    - void
    - DoSomething(...)
    - {
    - }

    PS F Ghandi

  6. C++0x by DreadSpoon · · Score: 3, Informative

    One of the proposed additions for C++0x includes Contract Programming functionality built into the core language/library.

    Do a Google search for "c++ std wg" to find the working group page, which includes a list of papers and proposals.

    1. Re:C++0x by NiceRoundNumber · · Score: 2, Interesting

      One of the proposed additions for C++0x includes Contract Programming functionality built into the core language/library

      In addition to assertions, there are a number of helpful ideas that can greatly improve the readability of the language and follow the intent of the programmer, as well as improve the generated code. For instance, a "pure" keyword that specifies that a function is deterministic and has no side-effects; e.g.,square root, or returning an inverted matrix. (So if the function is called twice on the same input, the compiler knows it only has to call the function once.)

      Similarly, a good system for handling pointer aliasing; specifying to the compiler which pointers may be aliased to which other ones, or which pointers are not aliased. These often lead to spaghetti code when hand-optimized, but if the concepts were embedded in the language, both the source code and output could become much cleaner.

      --
      Diplomacy is the art of letting other people have your way.
  7. The Pragmatic Programmer by Psionicist · · Score: 3, Informative


    The book The Pragmatic Programmer by Andrew Hunt and David Thomas has a chapter about Design by Contract. As it's a very good book (almost a classic) about lots of different things, I suggest you read it. Check out the reviews at Amazon, they are true.

    1. Re:The Pragmatic Programmer by mustafap · · Score: 2, Insightful

      >I suggest you read it.

      I agree. It's a great read. Made me glad to be a programmer.

      I'd also recommend "Code Complete".

      Read both once a year :o)

      Design by contract, like all the others, are just tools. Treat them as such, and use them when you feel appropriate. No matter how good a screwdriver you have, one is never enough.

      --
      Open Source Drum Kit, LPLC deve board - mjhdesigns.com
  8. Use AOP by LLuthor · · Score: 2, Informative

    I have only every used AspectJ, not AspectC so take this with a grain of salt. AOP is basically the holy grail of design by contract. You can decide and implement powerful contracts and assertions and apply them at compile time or runtime with very little effort. They can be maintained with the code itself or as a separate aspect implemented at a higher level.

    Best of all, you can use as little or as much as you want and it will not interfere with your current code.

    AspectC++

    --
    LL
  9. How about D by Hyram+Graff · · Score: 2, Informative

    The D programming language seems to support the idea of design by contract as a standard. From the litle I know about D, the language is close enough to C++ that a switch would be easy.

    --
    0*0
    00*
    ***
  10. Never use assertions to check input by coyote-san · · Score: 2, Informative

    I mostly agree with you, but there's one key difference. You should never use assertions in place of input validation. You must always code as if the assertions aren't there.

    BUT, and this is important, there are times when you can have a legitimate business decision to skip input validation when the cost of the checking is higher than the cost of a mistake, esp. when these are internal methods that should never get unsanitized input. In those cases you may want to have contractual assertions without a corresponding regular check. Those cases should be clearly indicated, e.g., by using a different set of assert macros.

    --
    For every complex problem there is an answer that is clear, simple, and wrong. -- H L Mencken
  11. Several options by Coryoth · · Score: 4, Informative

    There are several options. You can simply use macros as many people do. It's clunky and tends to have issues with inheritance and documentation, but it gets the job done. Alternatively you can try the digital mars c++ compiler which supports design by contract, or if your co-workers are willing to stretch a little bit you can try the D programming language from digital mars which is very similar to C++ but offers native contracts as well as a host of other nice features. Otherwise you can go the proprietary route and get C2 which is a C++ code generator that uses comment annotations to manage contracts and is a little slicker than the macro approach.

  12. Design by Contract already implemented by WalterBright · · Score: 2, Informative

    in Digital Mars C++. See contracts.