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++?"

7 of 114 comments (clear)

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

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

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

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

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

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