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

114 comments

  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.

    3. Re:In C++ by neves · · Score: 1
      I think you only have two choices. Use Eiffel or don't use contracts.

      The fact that you can't use all of DbC specifications, doens't mean that using a macro/asserts in C++ won't have any utility.

      We use a lot of pre/pos-conditions and they more than payed for themself. Each time a new feature crashes because a index was out-of-bounds, a variable wasn't initialized, or an invalid value was detected, we can solve it right away. It clears a lot of comunication problems between who codes and who uses a function.

      Use them. They are your friend.

    4. Re:In C++ by nickleaton · · Score: 1

      The invariant should only be checked when the code exits out of the class boundary. e.g. If I have two classes A and B. B calls a function on an object of class A. This function then calls another method on itself. It is only when the call come back to B, that the invariant needs to be checked. This is difficult to implement without help from the compiler. It is also interesting to compare assertions and unit tests. Assertions have a big advantage over unit tests. They are tested every pass through the code, not just for the cases that get tested by the unit tests. You get a lot more checking, for less effort. There are even tools that will 'unit test' code that has DBC. They generate lots of values that match the preconditions, run the code to see if the end result doesn't break the postconditions or assertions. Going forward, there is no doubt that DBC in the code is going to greatly help code checkers such as FxCop.

    5. Re:In C++ by jgrahn · · Score: 1
      The fact that you can't use all of DbC specifications, doens't mean that using a macro/asserts in C++ won't have any utility.

      I suspect that you can do some, but not all, of the Meyer design-by-contract stuff by using clever template programming. The Boost people have a collection of assertions, but I don't know whether there's anything DBC-related. If there isn't, there should be.

      The C assert() macro should be avoided in C++ code -- destructors will not be executed when an assert() fails.

    6. Re:In C++ by Lally+Singh · · Score: 1

      An assert failure's supposed to break right in the programmer's console or in the debugger -- d'tors aren't necessary, as it just slows the debugging process down.

      You do disable assert() in release builds, right?

      --
      Care about electronic freedom? Consider donating to the EFF!
  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 AuMatar · · Score: 1

      I'm not sure about the answer, but thats usually the problem.

      --
      I still have more fans than freaks. WTF is wrong with you people?
    3. Re:I don't understand the question... by Anonymous Coward · · Score: 0

      You forgot PERL. Well, ok, it's good for some things, but then so are shell scripts.

    4. 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.
    5. Re:I don't understand the question... by Anonymous Coward · · Score: 0

      Yeah, a natural language that FCC would not have tolerated, donkey or elephant.

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

    7. 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.
    8. Re:I don't understand the question... by psykocrime · · Score: 1

      For the worst language I have tried yet, I nominate PL/I.

      I'll see your PL/I and raise you an RPG/III (or, really, anything in the RPG family except *maybe* the ILE flavor of RPG/400).

      --
      // TODO: Insert Cool Sig
    9. Re:I don't understand the question... by RAMMS+EIN · · Score: 1

      What, you don't think that $_=!$g[$_]~=s/^\\\\/\\/g; is natural language? Looks like a perfectly good curse to me.

      --
      Please correct me if I got my facts wrong.
    10. Re:I don't understand the question... by EsbenMoseHansen · · Score: 1

      Hehe, I have no doubt RPG/III is worse :) I've never had the misfortune to try anything worse than PL/I.

      --
      Religion is regarded by the common people as true, by the wise as false, and by rulers as useful.
    11. Re:I don't understand the question... by zsau · · Score: 1

      For loosely typed, ... I haven't tried ... that functional language that is so popular these days, but I will get around to it.

      I'm not sure which you're referring to, but most non-lispy functional languages (that I know of) are actually strongly typed. For instance, Haskell is so strongly & statically typed that you don't always need to specify the types of a function or variable; it is obvious from the context that it takes only these types as arguments, and will only return this type.

      On the other hand, I've never really thought of C++ as being particularly strongly typed. More strongly typed than some languages yeah, but you can still treat chars as ints... (My C++ isn't very good, and I've managed to get various typing errors at run time causing problems. If it were strongly typed, they'd all've been caught at compile time.)

      --
      Look out!
    12. Re:I don't understand the question... by EsbenMoseHansen · · Score: 1

      Yeah, I was thinking of Haskell... which turns out to be strongly typed. Oh, well, I still want to try it out some day :)

      As for strongly typed... I don't usually take it to degrees :) C++ has lots of built-in conversions, but still a function takes types as parameters, and the compile will fail if an appropriate conversion cannot be found. (I find that this typed function is the most important part of the strongly typed system, as it is here most mistakes are made.) I have yet to encounter a language with no implicit type conversion at all... usually, at least something like float->double or B->A where B inherits from A is allowed. Working in such a language, I think, would be too tedious.

      --
      Religion is regarded by the common people as true, by the wise as false, and by rulers as useful.
    13. Re:I don't understand the question... by zsau · · Score: 1

      I was thinking more about the way two completely different things (like chars and ints) can be converted between. (Well, converting between '1' and 1 without casting wouldn't surprise me too much in the way that converting between 3.0 and 3 doesn't; but in C++ as in C you can use the same bit of memory as both '1' and ... 0x31 iirc.)

      Incidentally, I'm not actually sure that Haskell does do implicit typecasting; I don't know it well enough, but rather than being an integer, the literal 3 has the type of (Num t) => t, which means that it has the type of anything that's a number, kinda (the typeclass Num is a bit like an abstract class in Java which things like Ints, Integers, Doubles, Fractional (itself a typeclass) and the like implement). (+) has the type of (Num a) => a -> a -> a, which means it takes two numbers of the same type and yields a third number of that type. If you then go off and try to add up two numbers of different types, Haskell freaks:

      Prelude> (3::Int) + 3.1

      <interactive>:1:11:
              No instance for (Fractional Int)
                  arising from the literal `3.1' at <interactive>:1:11-13
              Probable fix: add an instance declaration for (Fractional Int)
              In the second argument of `(+)', namely `3.1'
              In the definition of `it': it = (3 :: Int) + 3.1


      or even:

      Prelude> (3::Int) + (3::Integer)

      <interactive>:1:12:
              Couldn't match `Int' against `Integer'
                  Expected type: Int
                  Inferred type: Integer
              In the expression: 3 :: Integer
              In the second argument of `(+)', namely `(3 :: Integer)'


      where 'Int' is a fairly run-of-the-mill int, but 'Integer' is more like a lispy bignum. Obviously the typeclass serve a similar function as implicit conversion or type weakness, as well as being something for poor object-oriented brains like mine to latch onto and say 'that's like home!'.

      --
      Look out!
    14. Re:I don't understand the question... by famebait · · Score: 1

      I think we need to introduce the term "unnatural language", just to cover perl and a few other behemoths.

      --
      sudo ergo sum
    15. Re:I don't understand the question... by EsbenMoseHansen · · Score: 1

      About the C++... primitive types are an abomination in any language (except C, which I regard as an assembler). I never consider them when I talk about strongly and loosely typed languages. It's the way that languages handles objects, which I am happy to see that most of the newer languages sees it this way too, thus 2.my_int_method() or equivalent is legal, like it should be. In your example, it would be relatively easy to make Character in C++ which would do the correct thing, quite unlike char :)

      As for Haskell.... those example looks like Haskell could be a real pain to work in :) Still, I suspect that same implicit casting would take place. Like casting from B to A, where A inherits for B. I still want to try it someday, but right now I'm having fun in Ruby on rails. That is one very smooth framework, I must admit.

      --
      Religion is regarded by the common people as true, by the wise as false, and by rulers as useful.
    16. Re:I don't understand the question... by zsau · · Score: 1

      Primitive types don't have to be an abomination in any language. You simply forbid something like 'a' + 3 from being valid syntax, and that solves one part of the problem. Creating a Character class in C++ would not be as efficient, and it can be, and do the right thing. And (worse) it means that all those things that are defined for chars, I have to define again. (I'm a little confused about where your 2.my_int_method() comment is meant to go; being able to do that sounds like it's merging the boundaries between the primative int type and a higher-level Int class, which makes it even less strongly typed in my mind. But I've been doing some programming in C++.Net this year (not worked with C++ before for anything non-trivial), and have been doing things like 2.ToString() and wondering why it works. Is that a C++ thing, or a .Net add-on like the ^ pointers? Is it syntactic sugar, or is 2 actually an object?)

      Regarding Haskell, it's not such a pain because you rarely work with things you know to be Ints or Doubles like you do in C++. Instead, you work with typeclasses. Typing the literal `3' doesn't get you a 3::Integer, it gets you a 3::(Num t => t),[*] so it could be an Integer, but it could be a Float, or it could be a user-defined type; we don't know yet (and might never), and so long as everything's compatible, we might as well never know. It achieves the same thing but in a different way.

      [*]: I have no idea if this is valid syntax or not.

      --
      Look out!
    17. Re:I don't understand the question... by EsbenMoseHansen · · Score: 1

      Making a class is just as efficient as using primitives, at least in C++. The end assembler code would be identical. Anyway, 'a'+3 makes pefect sense... it should be 'd' if it is a character or if it is a number (such as in C++), it should be 'a'+3. Why? Because a+3 = (((a+1)+1)+1)=(b+1)+1)=c+1=d. That is how it works for page numbers, e.g. What makes it hard in C++ is the shorthand 'a' for the "the character code for a". It does not mean the character a, which is *not* in accordance with the principle of least surprise, and that is indeed a bad thing. Just syntatic sugar gone a bit sour. Likewise, char is just a type suitable for representing a character code... it is not a character. Remember that , and you will do fine.

      In C++, 2 is not an object. In Ruby, e.g., it is. In my humble opionion, there is no good reason to have anything but objects in an oo language. Class should be an Object, Object should be an Object, methods should be an object etc. There is no reason not to. (The Java people will tell you otherwise. That is because every Java object lives on the heap, while primitives can live on the stack, and stacks are much more efficient. This is a language thing, and one of the weaker points of Java, imho).

      You are right that retrofitting C++ with a real character object would be an uphill battle; I think it is worth it, some do not. However, getting strings representation changed from char* -> const char* to std::string has gone reasonable smooth, so I remain hopeful :)

      I will refrain from commenting on Haskell until I have tried it :)

      --
      Religion is regarded by the common people as true, by the wise as false, and by rulers as useful.
    18. Re:I don't understand the question... by jgrahn · · Score: 1
      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).

      You mean "my favorite statically typed language". And yes, I know what you mean.

    19. Re:I don't understand the question... by EsbenMoseHansen · · Score: 1

      wikipedia on strongly typed. Check the first item on the list :p But I agree, I should have used the much more precise term, statically typed.

      --
      Religion is regarded by the common people as true, by the wise as false, and by rulers as useful.
    20. Re:I don't understand the question... by koreaman · · Score: 1

      Defend your assertion that C is an assembler.

    21. Re:I don't understand the question... by EsbenMoseHansen · · Score: 1
      From wikipedia:
      High-level assemblers provide high-level-language abstractions such as:
      Advanced control structures
      High-level procedure/function declarations and invocations
      High-level abstract data types, including structures/records, unions, classes, and sets
      Sophisticated macro processing

      Seems to fit the bill :p

      More to the point, when I need to know exactly which machine I will get, I use C. Or maybe really simple C++. Once, I would have used an assembler for this, but with a solid grasp of C and assembly, this is no longer necessary (for me, anyway)

      --
      Religion is regarded by the common people as true, by the wise as false, and by rulers as useful.
    22. Re:I don't understand the question... by Anonymous Coward · · Score: 0

      not so.
      in modern java, there is no heap or stack, or rather there is but there's also a multitude of other similar things, and things inbetween.
      java hasn't put all objects in a 'heap' since about version 1.2.
      it may be a weakness to have double and Double, but the weakness is nothing to do with 'where' the underlying representation is placed.

      and I don't see the problem in using the word char for a short short int.
      after all, a char was all it was ever used for.
      I doubt most C++ programs use char now anyway.

      and 2 is an object. it just doesn't inherit from some object class that you can inherit from. and you can't inherit from the type of 2. that's not unusual when using C++ libraries (although obviously libraries can provide you with all you need to make full use of the classes), and isn't a helpful way to think about built-ins.

  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 Gr8Apes · · Score: 1

      I'm sorry, but you must be somewhat mistaken. Eiffel sounds like a johnny come lately - yes, I know it's been around for a while. However Java, and C++ before it, had this concept called interfaces, and I'm sure something somewhere had the concept of Design by Contract long before then.

      Also, if you've done anything regarding integration like, say, EDI, then you've been designing by contract since the 60s.

      I just don't think this is as big a deal as the story makes out, and Eiffel certainly isn't the centerpiece.

      --
      The cesspool just got a check and balance.
    3. Re:Must Buy New Book For Latest Proggramming Fad! by Molt · · Score: 1

      Interfaces are not Design by Contract. Design by Contract is setting some conditions which are required to be true before a method can be called (preconditions), conditions which are in turn guaranteed to be true when the method returns (postconditison), and conditions which are guaranteed to be true all the way through a method's execution (invariants). Design by Contract can even be done in none-OO languages too.

      For example any accessor method can, by specifying invariants, be guaranteed not to change any of an object's state. If, for some reason, someone messes up and has this call a method which would change state then it's a compile time error.

      It's not something I've used much admittedly, but I remember having my brain twisted by Eiffel's trickery during Computer Science lectures so I don't see why others should avoid such fun!

      --
      404 Not Found: No such file or resource as '.sig'
    4. Re:Must Buy New Book For Latest Proggramming Fad! by Anonymous Coward · · Score: 0

      For example any accessor method can, by specifying invariants, be guaranteed not to change any of an object's state. If, for some reason, someone messes up and has this call a method which would change state then it's a compile time error.

      You mean exactly like the 'const' keyword on a class function in C++...

    5. Re:Must Buy New Book For Latest Proggramming Fad! by Anonymous+Brave+Guy · · Score: 1

      For example any accessor method can, by specifying invariants, be guaranteed not to change any of an object's state.

      No. Invariant conditions define what constitutes valid state for an object of the type in question. All objects should therefore satisfy their type's invariant conditions at all times, other than during updates when the object is in between two valid states. However, this is a very different concept from saying that the object's state must not vary.

      --
      If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
    6. 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'
    7. Re:Must Buy New Book For Latest Proggramming Fad! by Anonymous+Brave+Guy · · Score: 1

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

      But the language feature in such contexts is of limited value unless the checks are done at compile-time. Discovering at run-time that you're about to fry a patient is good only in the sense that you can diagnose that you screwed up and kick off any emergency shut-down procedure that is available. That's still better than not noticing and frying the patient, of course!

      --
      If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
  4. Wait, what? by Anonymous Coward · · Score: 0

    I have no idea what this is talking about. To wikipedia I go :)

  5. 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 Anonymous Coward · · Score: 0

      On the other hand, it gives the developers something to point to when the clients do the old "oh, that's not what we meant by..." routine when the project is over half-complete.

    3. 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
    4. Re:Verbal Contracts by Anonymous Coward · · Score: 0

      With all due respect, I think you are missing the point of DbC.

      From the viewpoint of software reliability, "verbal" contracts are just as good as no contracts at all. As someone says in the comments below, you have to have language support for DbC for it to have any kind of usefulness in being able to prove that your programs run the way you say they do, and this cannot be emulated through assert statements, never mind verbal agreements.

      You mention contracts as if they are loose or redundant documentation. In Eiffel, design by contract is not really meant as either. Invariants, preconditions and postconditions (as opposed to all other languages) are completely built in and are *guarantees* that your code is runs as intended. In true DbC, contracts mandate what input your code will take (not just types, but more sophisticated checks), and precisely guarantees how your program runs while it is running (class and loop invariants), and finally, in return for well-formed input, guarantee a particular result. Eiffel itself provides all sorts of useful features in return for filling out well-defined contracts that describe what your program does. This helps in testing and maintenance like you wouldn't believe. Real DbC is immensely useful in large scale software, but no less useful in medium-sized projects.

      I'm sure your verbal contracts are useful, but I hope that you can see that they simply aren't the same. Granted, it takes some experience in the field (and in getting burned!) to really grasp the advantages. Anyone who thinks DbC is some silly fad (as several comments above) is either not thinking critically or has a narrow range of experience in programming software.

    5. Re:Verbal Contracts by Nutria · · Score: 1
      On the other hand, it gives the developers something to point to when the clients do the old "oh, that's not what we meant by..." routine when the project is over half-complete.

      Now that is a damned good reason for DbC.

      But then, in the gov't contractor world, we do this all the time with the relevant agencies, no matter what the implementation language.

      --
      "I don't know, therefore Aliens" Wafflebox1
    6. Re:Verbal Contracts by Anonymous Coward · · Score: 0

      Another point to ponder in "verbal" vs. true DBC: When you're working in a consulting field (government or otherwise), you will often have to work with code that either you didn't write (and may or may not have access to the actual code) or work with code that you don't or are not allowed to see. You would have no idea if they followed the design plan, in fact, you may not even be able to ask such a question, or even know who or where the code came from. It's not uncommon to take a small business contract and have them hand you a library written 6 years ago "by that weird guy that we couldn't get ahold of so we hired you."

      With DBC, if you call a library's SuperNukeRocket::Launch() method, you KNOW that your inputs are right (otherwise it won't compile) and you KNOW that the result will be valid. You don't have to do your own error checking on a library's method or try to infer strange error conditions.

  6. Potential Pitfall by Anonymous Coward · · Score: 0

    Design by contract and invalid input.
    Remember: your top-level inputs are arbitrary strings. Somebody has to be contracted for checking for buffer overflow.

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

    1. Re:Simple Solution - Violence by Anonymous Coward · · Score: 0

      You're confusing a "contract WITH" with a "contract ON".

    2. Re:Simple Solution - Violence by marcosdumay · · Score: 1

      Don't do that. It is insensitive, and people will simply ignore your comment!

      Those comments go on the header (.h), not the source...

    3. Re:Simple Solution - Violence by mrchaotica · · Score: 1
      ...I will fucking kill you

      Oh great; now Steve Ballmer is going to come after your company for trademark infringment!

      --

      "[Regarding the 'cloud,'] ownership was what made America different than Russia." -- Woz

  8. 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.
    2. Re:C++0x by Anonymous Coward · · Score: 0

      Can anyone give me a solid reason to stick with C++ and not just switch to the DigitalMars D language? Honestly, C++ is a mess, and it's only getting messier with the committee grafting new ideas on top of the current poorly-designed mess. On the other hand, D is a pristine platform that already includes the stuff C++0x is going to provide years in the future, interacts beautifully with existing C/C++, and provides comparable performance.

  9. 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 Anonymous Coward · · Score: 0

      The Pragmatic Programmer is an excellent book, but you can't properly replicate Design by Contract using assert statements. For a start, Eiffel can handle the inheritance of "requires" clauses and will only need to check the assertion once. It is also easy to turn the differing levels of contract compliance on and off using the compiler, to examing the "short form" of an object, and so on. If you want DbC, use the real McCoy.

    2. 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
    3. Re:The Pragmatic Programmer by Anonymous Coward · · Score: 0

      Arrrrg once a year!!!! Code Complete is brutally long. I've been reading it for about 2 months :-P But both books are great.

  10. ASSERTing gets you a long way by Chris_Jefferson · · Score: 1

    The kind of design by contract you can get in some langauges is hard to replicate in C++. You can however get a long way, and I believe do a lot of useful work, but ASSERTing on all conditions at the start of functions, and on the return value, where approriate.

    I have a lot of this kind of code in my programs and it really helps find bugs, and more importantly find them where they first appear. The big advantage of using C++ and a tiny spot of macros is that they all the ASSERTs can be removed in your final build. Actually, I have 3 level of ASSERTs, mainly categorised on how long I expect them to take, how critical the code is and if the function deals with input from the user, so some level of sanity checks are left in final builds, and there is also a debug version which doesn't take too long (if you start checking all vectors to see if they are sorted at the entry to each function, you can rapidly get very slow code).

    --
    Combination - fun iPhone puzzling
    1. Re:ASSERTing gets you a long way by pla · · Score: 1

      You can however get a long way, and I believe do a lot of useful work, but ASSERTing on all conditions at the start of functions, and on the return value, where approriate.

      Do ANY of you work in the "real" world?

      "assert", in C, counts as a frickin' obscenity for anything that makes it out the door (now, for debugging, sure, throw 'em in like candy on Halloween, but make sure to remove every last one before release).

      End-users will, for the most part, deal with "odd" behavior. They tweak, however, when programs just arbitrarily exit. And for "mission critical" apps, far from reversing, the situation gets worse - Imagine an ATC system just randomly shutting itself down, not because of an unrecoverable error, but because of a design methodology buzzword... People die and programmers go to prison for bugs like that.

      ALWAYS check your inputs, but don't chuck the whole program in the middle of decrease_radiation_strength() because your call to format_a_string_real_pretty_like() didn't like the color-name passed to it.

    2. Re:ASSERTing gets you a long way by Cassini2 · · Score: 1

      I use the following rule when determining if an ASSERT should be used or an if-statment should be used:

      Does the condition you are testing for provably not exist in the release build?

      If the problem might occur in the release build, you need an if-statment. Somehow, I either succeed in proving I don't need the ASSERT or if at all (because the condition will not happen), or I put in an if-statment. Asserts have very limited value if you are building real-time code where every fault is significant, must be properly dealt with, and must be traced back to the source.

    3. Re:ASSERTing gets you a long way by ultranova · · Score: 1

      Imagine an ATC system just randomly shutting itself down, not because of an unrecoverable error, but because of a design methodology buzzword... People die and programmers go to prison for bugs like that.

      If someone's life depends on the program working as should, then don't use C. In fact, don't use any stack-based language, since stack-based languages don't have any inherent upper limit for memory use of a given program, so you could run out in some strange circumstances. For the same reason you don't want dynamic memory allocation. And direct memory access is an absolute no-no for obvious reasons.

      Mind you, you can still use functions and local variables, but a function can't call itself (directly or by any other function it called). Therefore, there is no way of getting recursion (which is good, since it removes the possibility of infinite recursion).

      Anyway, the point is that if we're talking life and death, you don't use C, you use a language designed for the task. Because, while it is possible to write bugless code in C, you aren't a good enough coder. Anything that can go wrong will go wrong at the worst possible moment - so better make sure that there's nothing that can go wrong.

      ALWAYS check your inputs, but don't chuck the whole program in the middle of decrease_radiation_strength() because your call to format_a_string_real_pretty_like() didn't like the color-name passed to it.

      Why on Earth are you formatting strings in the same process and memory space you are controlling radiation strength in ? You separate them, so that if the UI dies the patient won't.

      Don't integrate vital systems - separate everything you possibly can from the truly vital part, the radiation controller. This is especially vital in C, where the string handling functions will bleed all over the program memory space and die at some point.

      --

      Forget magic. Any technology distinguishable from divine power is insufficiently advanced.

  11. 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
    1. Re:Use AOP by AuMatar · · Score: 0, Troll

      AoP- for when you want to use a goto but it just isn't buzzwordy enough.

      --
      I still have more fans than freaks. WTF is wrong with you people?
    2. Re:Use AOP by Anonymous Coward · · Score: 0

      AOP is basically the holy grail of design by contract.

      AOP -- a holy grail for Java/C++ programmers; a special case of macros for Lisp programmers.

      (Yeah, yeah, go ahead and mark me Troll...)

  12. Digital Mars C++ by Anonymous Coward · · Score: 0

    While it is a non-trivial thing to switch C++ compilers, Digital Mars C++ is a free (as in beer) compiler that has DBC built in as a language extension. Here is the link to the relevant documentation. http://www.digitalmars.com/ctg/contract.html One thing I think it nifty is the __invariant contract keyword. While __in and __out can be duplicated easily with #ifdefs, __invariant really has to be supported at the language level. I believe DMC++ also handles contract inheritance for class hierarchies (although I have not played with this personally).

  13. What the...? by codered82 · · Score: 1
    Design by Contract in C++?...
    Eiffel?
    Uh? Who? What? ...for how many cookies? I get the impression I need to get into more mainstream developement. I have not a clue what this is all about.

    Article: +10 (Obscure to a VFP Programmer)
    --
    History does not long entrust the care of freedom to the weak or the timid. ~Dwight D. Eisenhower
  14. 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*
    ***
    1. Re:How about D by doti · · Score: 1

      I second that.

      I have heard of D before, but now I went for a closer look, and just fell in love with it.
      I'm currently writing a Qonk clone in D, it's very elegant and comfortable to work with.

      The major problem is that it can't bind with C++ libraries (plain C works ok, my game even uses SDL, and I already tested a small OpenGL program too.)

      See an overview of D, and read about it's contract implementation.

      --
      factor 966971: 966971
    2. Re:How about D by Anonymous Coward · · Score: 1, Informative

      You mean the programming language which it's author keeps on spamming the C++ newsgroups about how great D is and how everyone should drop C/C++ and move to D?

      Do you mean the programming language which the author, trying to compare it to other languages in terms of features, insists on ignoring obvious functionality and features of the other languages and insists on ignoring and not correcting the comparissons even when hordes of messages informing and demonstrating him that his comparisson are full bullshit? For god's sake, the man claims that C++ doesn't have resizeable arrays, built-in strings, garbage collection or even class properties!

      Do you mean the programming language which the author, in the code comparisson between D and other languages, insists in writing piss-poor, mangled code in the other language examples and insists on presenting that same piss-poor code even when hordes of complaints and corrections are sent to him?

      No thanks. The D programming language is simply a C++ clone with cosmetic changes and braindamaged options which doesn't offer anything new or better than C++. To top things off, the author is a troll who acts like he wants a piece of the admiration that Stroustrup gets.

    3. Re:How about D by myzz · · Score: 1
      You seem trollish, but anyway...

      For god's sake, the man claims that C++ doesn't have resizeable arrays, built-in strings, garbage collection or even class properties!

      • Resizeable arrays - quote from D website:
        Part of the standard library for C++ implements resizeable arrays, however, they are not part of the core language. A conforming freestanding implementation of C++ (C++98 17.4.1.3) does not need to provide these libraries.
        Although std::vector has always been good enough for me.
      • Garbage collection - quote from D website:
        The Hans-Boehm garbage collector can be successfully used with C and C++, but it is not a standard part of the language.
      • I would be glad, if you can share, how the class properties can be done sanely in C++. It is technically possible to use special class with overloaded = as a public field of C++ class, but it is cumbersome enough to redirect the getter-setter methods to main class, that you probably don't bother. Furthermore, it is not possible to override those properties in child classes (using D inbuilt class properties it is imho possible).
      About stuff that you ignored in D - it has lambda functions (calling them delegates), which are practically impossible to emulate conviniently in C++ (I know about boost hacks - these are not anywhere near convinient lambdas or first-class functions).

      Still, I personally don't use D. OCaml is simply nicer with really cool data types, pattern matching and more convinient syntax ;)

    4. Re:How about D by Anonymous Coward · · Score: 0

      No thanks. The D programming language is simply a C++ clone with cosmetic changes and braindamaged options which doesn't offer anything new or better than C++.

      Sounds like you are just as misleading as you claim he is.

      D offers many, many features that don't exist in C++ at all, including DBC as the original poster was interested in.

      Not sure what "braindamaged optoins" you are referring to.

      I'll take the word of a guy who has spent perhaps decades writing C, C++ and D compilers over the word of a troll who makes baseless statements disparaging D and its creator.

  15. 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
    1. Re:Never use assertions to check input by Chris_Jefferson · · Score: 1

      No, you definatly shouldn't use asserts to check input validation, I should have been more clear about that, sorry.

      In general, I program with the aim that no assert should ever fire under any cercumstance. Of course, it turns out they then end up firing annoyingly often :)

      --
      Combination - fun iPhone puzzling
  16. Contracts in Another Language by bheilig · · Score: 0, Offtopic

    > -----Original Message-----
    > From: James Heliotis [mailto:jeh@...]
    >
    > I have a student who is interested in doing a project adding
    > design-by-contract assertions to another language. To my memory,
    > I have never seen anything about how assertions are implemented in
    > EiffelStudio, and what the challenges and pitfalls were. Can anyone
    > point me to any documentation?
    >
    > Thanks a lot,
    > James

    Dear Jim:

    Your student should find the following links useful:

    http://www.phact.org/e/dennis4.html
    http://mathworld.wolfram.com/CircleSquaring.html
    http://chemistry.about.com/cs/generalchemistry/a/a a050601a.htm

    Hope this helps,

    -- Bertrand Meyer

    http://tech.groups.yahoo.com/group/eiffel_software /message/3558

  17. DBC for C++ by Skapare · · Score: 0

    Maybe you just want to start here.

    --
    now we need to go OSS in diesel cars
  18. 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.

  19. Just wait for Boost to get around to it by try_anything · · Score: 1

    I can see it now: write contracts in a new template language, use template parameters to control run-time checking, and since it's all pure C++ (no macros), you can produce the contract documentation from the output of gccxml.

    I mock, but now I really want to try it. Off to hack my own half-assed version -- Friday nights rule!

    1. Re:Just wait for Boost to get around to it by Anonymous Coward · · Score: 0

      Or you could spend your Friday nights using OCaml, which offers such functionality without the hassles of C++ templates. It's not as good as pussy, but you'll still cream all over yourself.

  20. OT: Forget design by contract, I want to know... by Anonymous Coward · · Score: 0
    What number is similar to 6?

    There are six engineers working on my part of the project (the embedded part), and a similar number working on the other parts.

    9 is similar to 6, but they are not the same.

    Vague specs are usually the problem when software projects go awry.

  21. What's so special about Eiffel's capabilities? by Sirp · · Score: 1

    Having only very passing familarity with Eiffel, I'm not sure if I'm missing something, but I don't understand any significant benefit Eiffel's capabilities have over C++'s or a host of other languages with respect to design by contract.

    So it has funky keywords to specify what the pre-conditions, post-conditions and invariants are, but is this really any different to putting assert() statements at the begin and end of your functions?

    The obvious improvement in this area would be mathematically proving the pre-conditions, post-conditions, and invariants are always satisfied at compile time, but from the Eiffel overview of Design by Contract, it sounds like Eiffel only checks at runtime, the same way C++ does it. Is this correct? If so, what does Eiffel provide exactly that is better than C++ in this regard? Or is it just a little syntactic sugar to make the different kinds of assertions a little more clear?

    1. Re:What's so special about Eiffel's capabilities? by Coryoth · · Score: 1

      As someone else pointed out, Eiffel, or anything that takes design by contract seriously, adds more than just keywords. Good design by contract should ahve contracts behave properly with respect to inheritance (preconditions can only be weakened, and postconditions and invariants can only be strengthened) with contracts being inherited properly even in overidden methods. Eiffel also allows much more fine grained control of runtime checking of contracts than asserts and ifdefs can give you unless you spend a lot of time and have complex layered ifdefs. Good DbC also offers more than just require and ensures, it also has keywords like "old" (to refer to the value of a variable upon entry to the method), and logical connectives like "implies" and "if and only if" to allow for greater expressivity of requirements. Good DbC also involve s a certain amount of smartness in when conditions are checked - there's actually come subtlety. For instance, should you check an invariant after a method completes even though that method was called by another method of the same object which is still continuing (the answer, of course, is no)? Good DbC also integrates efficiently and easily into autogenerated documentation so contracts are fully documented from the outset.

      Yes, throwing in assertions is good, and can save you a lot of trouble tracking down bugs. That doesn't, however, make it equivalent to a good DbC system like Eiffel, JML, SPARK, or Spec#.

    2. Re:What's so special about Eiffel's capabilities? by Anonymous Coward · · Score: 0

      boolean a,b;
      a iff b is the same as a==b
      a => b is the same as (a?b:true)

    3. Re:What's so special about Eiffel's capabilities? by maxwell+demon · · Score: 1
      Good design by contract should ahve contracts behave properly with respect to inheritance (preconditions can only be weakened, and postconditions and invariants can only be strengthened) with contracts being inherited properly even in overidden methods.

      You can get most of that in C++ by using the idiom of public non-virtual functions calling private virtual functions:
      class Base
      {
      public:
        int something(int whatever)
        {
      // check preconditions
          int result = do_something(whatever);
      // check postconditions
        }
      // ...
      private:
        virtual int do_something(int) = 0;
      // ...
      };
      Now everyone calling something(int) will get the checks defined on the base class, but the actual virtual function from the derived class. Derived classes cannot override the base class version, so calls through base class pointers/references will always use the base class checks, even if the derived class defines its own version with different checks. The only part that cannot be checked by the compiler is that derived classes don't weaken the post-conditions or strengthen the preconditions.
      --
      The Tao of math: The numbers you can count are not the real numbers.
    4. Re:What's so special about Eiffel's capabilities? by maxwell+demon · · Score: 1

      Well, actually you can derive all logical operations just from ?: and the constants true and false.

      !a is the same as a?false:true
      a&&b is the same as a?b:false (even the shortcut behaviour is right!)
      a||b is the same as a?true:b (again, with the correct shortcut behaviour)
      a==b is the same as a?b:b?false:true
      a!=b is the same as a?b?false:true:b

      Especially the latter ones are probably quite nice for IOCCC :-)

      --
      The Tao of math: The numbers you can count are not the real numbers.
    5. Re:What's so special about Eiffel's capabilities? by brpr · · Score: 1

      The definitions for (in)equality only work if the only possible values are True or False.

      --
      Freedom is not increased by mere diminuation of government. Anarchy is freedom for the strong and slavery for the weak.
    6. Re:What's so special about Eiffel's capabilities? by Coryoth · · Score: 1

      It's a nice idea, but then you run into the problem of strengthening or weakening contracts in sub-objects, and if you have lots of classes, and hence lots of different base classes, then turning runtime checking of contracts on and off is not so easy. That's not to say it isn't a good idea and doesn't have value, especially in a language that just doesn't have any DbC facility, but it isn't a replacement fr good DbC.

    7. Re:What's so special about Eiffel's capabilities? by maxwell+demon · · Score: 1

      Since a and b were explicitly declared as boolean (in the posting I answered to), the values cannot be anything but true or false. Indeed, if equality is meant to implement iff, it's actually a feature if a and b are implicitly converted to bool instead of (erroneously) comparing the actual non-bool values.

      --
      The Tao of math: The numbers you can count are not the real numbers.
  22. Might as well ask why we type variables. by Inoshiro · · Score: 1

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

    Yea, we have meetings anyway. Let's just make every variable in the system of no specific type. Let's use them as we need them, how we need them. We can verbally agree that we'll always use ints, floats, strings, etc. No point making that compiler do any permission checking or such. Who needs provably correct code? Besides, as a project evolves, it sure sucks to change that int to a float by hand.

    Oh, wait, no that'd be stupid. Why don't we have the compiler enforce compile-time and run-time checks on things? I mean beyond the fact that eStudio is ungodly evil incarnate, and Eiffel itself is overly encumbered with PASCAL/Modula-2 syntax. There is no good reason.

    --
    --
    Internet Explorer (n): Another bug -- that is, a feature that can't be turned off -- in Windows.
    1. Re:Might as well ask why we type variables. by Anonymous Coward · · Score: 0

      Yea, we have meetings anyway. Let's just make every variable in the system of no specific type. Let's use them as we need them, how we need them. We can verbally agree that we'll always use ints, floats, strings, etc. No point making that compiler do any permission checking or such. Who needs provably correct code? Besides, as a project evolves, it sure sucks to change that int to a float by hand.

      Sadly thats exactly what happens with large projects written in python.

    2. Re:Might as well ask why we type variables. by afd8856 · · Score: 1

      Which is rectified by python programmers getting smarter. Look at Zope 3 Component Architecture to see the progress being made.
      Using the Z3 CA the type of an object is irelevant. Does it implement the necesary interface? If yes, cool, if not, write an adaptor with a class factory that would implements that interface.
      And come on, python it's not php. If you do: mystring = 10 + "something", that's not gonna work.

      --
      I'll do the stupid thing first and then you shy people follow...
    3. Re:Might as well ask why we type variables. by moonbender · · Score: 1

      Funnily enough, that'll work just fine in Java.

      --
      Switch back to Slashdot's D1 system.
  23. Nobody said the obvious! by Anonymous Coward · · Score: 1, Interesting

    Here's this guy working for a company that exists, apparently has cashflow, and at least has some products that are actually working and that customers are buying. So he watches this video that talks about some cool shit, and wants the other programmers at his work to switch over to this cool shit, that may be cool and may also be shit for what they're doing.

    It's not just a matter of adding yet more lipstick to that pig, and it's not just a matter of using another language instead. There's an entire infrastructure of concerns that need to be coherently operative as a system. Does it need to run fast? Bye bye Ruby. Does it need to have lots of graphics? Bye bye huge numbers of academically cool and yet real world shit languages.

    Forget stuff like design by contract until you've actually established that the language actually has the normal everyday boring functionality that has you yawning in boredom, but which your arse is getting fired if you don't do. Forget aspect orientated programming and all the cool shit (damn, it's cool! AND SHIT!) until you've worked out the changeover costs, the additional overhead of supporting more than one language in-house until the old uncool (but working) stuff is completely phased out.

    Work out the business costs, and even more so, work out the business reasons as to why people should spend time and effort changing over vast swathes of your internal IT operations to some trendy new concept that isn't even proven past "that sounds like cool shit". Languages work and don't work for incidental reasons, rarely for specifically designed reasons. If it were purely merit, then Scheme would be what C is now.

    Stop flailing around looking for some magic arse concept that will silver bullet everything - it's all shit. Nothing cool has been invented since John von Neumann threw together some cool shit and died before he got around to version two. What you see in front of you is a big pile of quickie crap thrown together in wartime without a hell of a lot of thought put into it. So it's all going to suck regardless of whatever crappy abstraction gets put over the top.

    And like putting lipstick on that pig, there's a lot of money to be made making the lipstick and selling it to stupid little piggies.

    1. Re:Nobody said the obvious! by Anonymous Coward · · Score: 0

      Hmmm. Tell me more about this pig, including the lipstick it wears.... Is it *red* lipstick??

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

    in Digital Mars C++. See contracts.

    1. Re:Design by Contract already implemented by GRNXNM · · Score: 1

      Man Walter, your compilers are sweet! I've been a fan of them since you single-handedly wrote Zortech C++ (the world's first native C++ compiler). I was VERY happy to abandon my Cfront preprocessor in favor of a native compiler. And Zortech was one speedy compiler too.

      Has anyone out there been following Walter's new language: D

      It also supports contract programming, as well as a host of other sweet features. Very nice!

  25. simple class template for pre-/postconditions by Anonymous Coward · · Score: 0

    while this might not be true to the spirit of 'real' dbc, it's certainly better than using assertations, because it becomes part of the interface design rather than part of the implementation: wrap parameters and return values. create a templated class that's defined by a valueT and a policyT (the policyT should be chainable if you want to check for more than one condition). make sure your class can be used as much as a valueT as you would like. most importantly, it should be able to be copy-constructed from a valueT, and in the ctor run the (possibly chained) policyT to ensure that the passed valueT holds values it likes. if it does, then just proceed. if it doesn't, then throw.

    it'll look a bit cumbersome to code, but it'll ensure that the code in your function won't run if the parameters passed don't meet your conditions. similarily, a function returning such a wrapped value will throw on exit if it's post-condition isn't met.

    the difference to assertations? it's part of the function's prototype, so a) code, b) highly visible (especially since it can look rather ugly) and c) gets inherited. and if it throws you can even recover from it (as opposed to the standard assert() macro).

    i've started putting together a _nice_ class a few months back, but got sidetracked after a day or two. maybe i should take a look at that again, huh?

  26. Artima by Profound · · Score: 1

    I have seen a number of articles on DBC & C++ on Artima

    A quick google came up with:

    http://www.artima.com/cppsource/deepspace.html

    though search the Artima site and I'm sure you'll find lots more.

    Another one:

    http://www.ddj.com/184405997

  27. Why Assert when you can throw an exception? by Anonymous Coward · · Score: 0

    I can't see why many people are discussing Assert to implement this function. Why not throw exceptions?

  28. Design by contract by Anonymous Coward · · Score: 0

    Our house chucked the single letter language long ago and it cleared up a LOT of bugs. There are too many cleaner, simpler languages to continue beating your head against that wall. My favorite is FreePascal, but Python, Rebol and Java come in a close second. Cheers!

  29. A few simple techniques by Craig+Ringer · · Score: 1

    The first thing to understand is that eiffel's design-by-contract features sound a lot nicer than they are. They could be very good, but most (all?) current compilers pretty much just translate them to a bunch of run-time precondition and postcondition assertions, which I find pretty yawn-worthy. Of course, I'm *VERY* far from an Eiffel expert, so feel free to politely correct me if the above is bunk.

    I've been happy ensuring that:

    - Every non-trivial object has a private invariant() method that is called at the completion of its ctor and any non-const qualified method. This helps to ensure that the object is internally consistent. It's expensive though so it's something I usually make a build-time option.
    - Every method asserts its pre- and post- conditions.
    - Extensive sanity checking is preformed wherever else it makes sense.

    in my C++ code, and doing so has prevented more than a few bugs. That said, *nothing* is as effective in my experience as writing comprehensive unit tests that consider all the corner cases you can think of, combined with coding using safe and automatic memory management (not necessarily a gc; good use of automatic stack objects, auto_ptr, std::tr1::smart_ptr / boost::smart_ptr and other devices for tracking and managing memory ownership and allocation can be as good or better for many use cases).

    --
    Craig Ringer

    1. Re:A few simple techniques by Coryoth · · Score: 1
      The first thing to understand is that eiffel's design-by-contract features sound a lot nicer than they are. They could be very good, but most (all?) current compilers pretty much just translate them to a bunch of run-time precondition and postcondition assertions, which I find pretty yawn-worthy. Of course, I'm *VERY* far from an Eiffel expert, so feel free to politely correct me if the above is bunk.

      What you want, I think, would be some sort of extended static checking using the contracts and an automated theorem prover to warn you of, for instance, bizarre corner cases you hadn't thought of that might allow contracts to be violated. Such things do exist, though strangely for Eiffel they're a little behind - for Eiffel there's a system for doin this still in development. For Java there's ESC/Java2, which requires you to annotate your java with JML to get the contracts, but once you've done that does a truly remarkable job of finding interesting errors you would more than likely miss (as well as obvious ones too). Better still running ESC/Java2 over a codebase takes about as long as the compile step, so it's easy to do regularly.
    2. Re:A few simple techniques by Anonymous Coward · · Score: 0

      why do you care what the compiler does?

      it's not going to complain that its job is boring and go work for google.

      your maintenance programmers faced with maintaining a million cryptic asserts all over the place (which will perforce be bound to your implementation rather than the point of contracts which is that they bind to the interface) are either going to leave, or search-and-replace them all away.

      asserts are a shitty attempt at contracts, don't work properly anyway, and put the burden on the coder rather than the designer/compiler.

  30. Imperfect C++ by Anonymous Coward · · Score: 0

    Try the book Imperfect C++: Practical Solutions for Real-Life Programming by Matthew Wilson. I haven't read it in a while, but the first chapter is Enforcing Design: Constraints, Contracts, and Assertions. The discussion focuses largely on how to implement contracts with the template mechanism. If I recall, the technique works, but he warns that enforcement works by issuing potentially indecipherable template compile errors. That is, the technique blocks you from compiling code that breaks the contract, but the error message is so obtuse that you may spend five to ten minutes to figure out why.

  31. Use macros and Condition classes by angel'o'sphere · · Score: 1

    I one wrote an article about that in magazine and described a schema which I used a while.

    First: all conditions are classs that inherit from an abstract base class that defines the methods checkPecondition and checkPostcondition, the methods do the same, just checking the condition but throwing different exceptions. (Basically you overwrite only the checkCondition method and implement the constructor to call the checkPrecondition() method.)

    Example:

    class BaseCondition {
            public:
            virtual ~ BaseCondition() { checkPostcondition(); }
            virtual bool checkCondition() = 0;
            virtual bool checkPrecondition() { if (!checkCondition()) throw new PreconditionViolation(this); return true; }
            virtual bool checkPostcondition() { if (!checkCondition()) throw new PostconditionViolation(this); return true; }
    }


    Second:
    you make some macros, like ensure(x) and require(x), invariant(x). The code of those is simple, I ommit it here. They all only allocate an object of the given class on the stack, require calls checkPrecondition(); ensure does nothing but waits for the stack unwinding so the destructor of the condition is called which performs the post condition check. Invariant(x) does both.

    Problems are like some people said: oring preconditions and anding post conditions needs to be done manually.
    Invariants are a problem if your method calls other methods with pre/post conditions

    Biggest problem:
    You use this only in the implementation of your code like:

    void myMethod(int a) {
            require(GreaterZero(a)); // GreaterThanZero is a class!
            ensure((FieldXIsSet(this)); // FieldXIsSet is a class, too! // ... your code here
    }


    So, you wont see the contract in your header files unless you put the production code into its own methods and wrap it in the header files accordingly.

    Advantage: as all conditions are classes they can freely be reused and combined.

    Biggest disadvantage: the compiler knows nothing about all that, unless like in Eiffel where the compiler would reject calls and flag them as error where it can statically descided.

    angel'o'sphere

    P.S. oops, I see now it was more complicated to implement. The macros instanciated a template class with the Condition class as argument, and called the pre/post condition checks. That means you don't have to do complicated constructor and destructor implementatison but only have to have a class as condition with a defined method whcih can be callled from a template. Mail me if you need it concrete, I think I can dig that stuff out from an old computer.

    --
    Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
  32. someday Java will steal it by not+a+cylon · · Score: 0

    I'm sure some future version of Java will proudly proclaim the "breakthrough" of supporting contracts. In the same way they made a big deal of finally implementing generics.

    Eiffel: proof that the best technology doesn't always win.

  33. my 2 cents on 15 years by hzamir · · Score: 1
    I have been using contracts in C++ since 1991, so I have some experiences to report.

    First off, I wrote a little paper on it at the time.

    I implemented it with macros. The main issues were:
    • It required a funny return macro, to guarantee exiting through the postconditions
    • Compilers started to complain about gotos crossing over my variable declarations. (I tried to put pre and post conditions at the top of the function, jump past the postconditions, and then on return jump back to the postconditions to execute them. This approach had serious issues, and would force me to declare some variables higher up.)
    Despite the admitted problems, it was a radically successful effort, eliminating a whole class of bugs for me--most importantly in the area of attempted reuse of classes where I saved tons of debugging time. (Like the time I attempted to reuse a dictionary class, not realizing that my dictionary did not accept certain types of keys, or the time I found out with the same class that I was generating negative hashcodes.) It never ceases to amaze me how some of the world's most important programming constructs--particulary for correctness--have not made it into mainstream languages.
    1. Re:my 2 cents on 15 years by Anonymous Coward · · Score: 0

      oh dear.

  34. dynamic/static by krischik · · Score: 1

    dynamic/static is what you mean. Try some reading:

    http://en.wikipedia.org/wiki/Type_system#Types_of_ Types

    Of corse C++ adcocates change the C++ entry to there liking faster then you can corect it but as far as I see it a language which allows:

    unsigned i = -1;

    is not strongly typed. In fact and just for good measure:

    #include <iostream>

    int
    main ()
    {
    unsigned i = -1;

    std::cout << i;

    return i;
    }

    >g++ test.cpp -o test
    /tmp Linux martin@linux2 Mi Sep 27 20:47:18 standart
    >./test
    4294967295

    The printout is neither an exeption dump nor a -1 so C++ is weakly typed.

    Martin

    1. Re:dynamic/static by EsbenMoseHansen · · Score: 1

      I am very much aware of the dynamic/static issue. C++ is (almost, if you ignore dynamic_cast and friends) statically typed language. That is hardly the point.

      A strongly typed language is a very poor term, as it is used for so many things. The Java crowd, especially, uses it as a bagde of honour, even though Java allows some implicit casts (which is usually their definition, strangely enough) But the definition I use is that a language is strongly (statically) typed, if a) every variable has a type b) conversion from one variable to another is only accepted if there exist a conversion operator from a to b. I know this one is only one in dozens, but it makes more sense than most. Most languages are strongly typed in this sense, but many are only so dynamically. In the example above, signed->unsigned succeeds since there is a (implementation defined) conversion operation between the two. Just like you can assign a float to a double in Java. You might, as I do, think that there is too many of those between primitive types in C++, but the difference is a more vague of "making sense" or similar.

      --
      Religion is regarded by the common people as true, by the wise as false, and by rulers as useful.
  35. 4 Dimensional Typing System by krischik · · Score: 1

    The mistake you are making (and you are not alone here) is to assume that strongly impies static. But that is not true - the typing system is 4 dimensional:

    static/dynamic: Can a variable change type?
    strong/weak: Are types converted implicidly?
    safe/unsafe: Are data convertions save? This includes dangling pointers!
    nominative/structural: Are types bound to the a more or to the structure?

    Some combinations are more common then other but in theory any combination is possible. And quite often a language us not 100% one or the other.

    Martin

    1. Re:4 Dimensional Typing System by EsbenMoseHansen · · Score: 1

      *Sigh* I already wrote once that I am well aware of these distinctions. I admit to not be 100% exact, but my usage of the word is very common (it's the top suggestion on wikipedia e.g.), and anyway, it was not important. Strongly typed languages in your sense are too impractical as far as I can see. I don't know any offhand.

      And 4-dimensional? You could go on. E.g, some type systems have const/non-const capabilities, which are othogonal to everything mentioned above.

      As for the 100%, all those except the fluffy safe one (sounds more like marketing than computer science) are either-or. Either you allow an implicit conversion, or you do not. Either you infer the type solely from the methods, or you do not.

      --
      Religion is regarded by the common people as true, by the wise as false, and by rulers as useful.
    2. Re:4 Dimensional Typing System by krischik · · Score: 1

      The strongest typed language which I am aware of is Ada - and Ada indeed does not allow implicid type convertins between types. However Ada also has the concept of subtypes and will implicidly convert between them and allows for explicid type conversion. See:

      http://en.wikibooks.org/wiki/Ada_Programming/Type_ System

      All in all I consider the Ada type system very praktical indeed. It allows me express my typing needs in a way I have never seen in any other programming language.

      Martin

  36. It does matter by Craig+Ringer · · Score: 1

    That's exactly the point.

    The current Eiffel compilers essentially convert pre- and post- condition sections to assertions. Faults are not detected until runtime when that code is excersised. A comprehensive test suite with full code coverage is necessary.

    In other words, they don't do anything better than assertions used according to suitable conventions - except look prettier.

    I'm not sure what you're getting at with respect to "a million cryptic asserts all over the place (which will perforce be bound to your implementation rather than the point of contracts which is that they bind to the interface)" - in that assertions used as interface contact checking will be present only at interface entry and exit points (like contract blocks) and no more cryptic than contract block entries, which they're logically equivalent to. I'd _prefer_ them in contract blocks, but with something as simple as a standard comment to deliniate where they begin and end it's not a big issue.

    Now, if Eiffel compilers started doing some static analysis to validate interfaces at compile time then I might care, because there's something I can benefit from that I _can't_ get from well used and documented assertions. The advantage of using contract blocks might be that while Eiffel compilers can't do this now, theoretically they might in the future. On the other hand, I'd have to endure a more limited set of available libraries, the irritation of talking to C++ code via C adapter interfaces, and quite a bit more besides for a benefit that may never arrive.

    I'll stick with my test suite (which I'll need anyway) and careful documented use of assertions to check the interface behaviour, I think.

    --
    Craig Ringer