use of assert in Java [vs. exceptions]

Discussion in 'Java' started by Giovanni Azua, May 30, 2009.

  1. Hello,

    This is a follow up to the thread "Where should I throw RuntimeException".
    At some point the topic regarding the use of assertions took over that
    thread discussion.

    Before moving into the concrete arguments I wanted to present the following
    definitions by Bertrand Meyer:

    Defensive programming: "A technique of fighting potential errors by making
    every module check for many possible consistency conditions, even if this
    causes redundancy of checks performed by clients and suppliers. Contradicts
    Design by Contract." [1, p1195]

    Design by Contract: "A method of software construction that designs the
    components of a system so that they will cooperate on the basis of precisely
    defined contracts. See also: defensive programming." [1, p1195]

    "Assertion Violation rule (1) A run-time assertion violation is the
    manifestation of a bug in the software." [1, p346]

    The key in the defensive programming definition is "check". It doesn't
    really matter what is done after encountering the problem either throwing
    exceptions or programming an alternate way e.g. Math.sqrt that handles the
    special case of negative input by returning Double.NaN. Please note that
    neither Eiffel "require" nor the Java "assert" for verification of pre
    conditions would fall under the category "check", by definition Design by
    Contract (DbC) is not a check, they are enabled only optionally and for
    discovering programming errors. Granted that Java assert feature is a small
    subset of what Eiffel DbC offers [3, p15 "So, is it like 'assert.h'"].

    The point I was defending was that Sun's commended way to use assertions was
    too categorical "Do not use assertions to check the parameters of a public
    method" [2]. The reasoning for my discrepancy towards that rule is that
    programs should not handle pre condition violations that are rooted in
    programming errors by means of exceptions e.g. IllegalArgumentException.
    However, the case of user input validation is a good use-case for using
    IllegalArgumentException. In general, exceptions are meant to be handled
    programmatically. You can't nor should recover from programming errors but
    rather *fix* them e.g.

    Defensive alternative A:

    public void defensiveMethod(...) throws IllegalArgumentException {
    // first checks
    if (/* some input programming error condition */) {
    throw IllegalArgumentException("Caught just another bug");
    }

    // some checks
    // some more checks ...

    // now we are "safe", do the real business
    }

    // a possible client
    try {
    defensiveMethod(...);
    }
    catch (IllegalArgumentException exception) {
    // what can you possibly do here? maybe we could ...
    //
    // - retrieve class name of the caller
    // - get the author name out of the java file
    // - send her an email complaining to FIX her code!
    }

    vs.

    DbC alternative B:

    public void dbCMethod(...) {
    // assert-based pre condition verification. Assertions
    // will be disabled once all programming errors are
    // corrected

    // assert-based class invariant verification

    // do the real business

    // assert-based class invariant verification

    // assert-based post-condition verification
    }

    Defensive programming as defined by Bertrand Meyer above yields the
    following negative consequences in software engineering:

    - degrades performance
    - predates reliability
    - increases complexity
    - provides only a subjective sense of safety
    - increases code duplication, redundancy
    - scatters concerns across disparate layers

    A few excerpts from Bertrand Meyer's book:

    "Non-Redundancy principle: Under no circumstances shall the body of a
    routine ever test for the routine's precondition." [1, p343] For the example
    that depicts such case he writes "is not just unnecessary but unacceptable"
    [1, p343]

    "... complexity is the major enemy of quality. When we bring in this
    concern, possibly redundant checks do not appear so harmless any more!
    Extrapolated to the thousands of routines of a medium -size system (or the
    tens or hundreds of thousands of routines of a larger one), the if x < 0
    then ... of sqrt, innocuous at first sight, begins to look like a monster of
    useless complexity. By adding possibly redundant checks, you add more
    software; more software means more complexity, and in particular more
    sources of conditions that could go wrong; hence the need for more checks,
    meaning more software; and so on ad infinitum. If we start on this road only
    one thing is certain: we will never obtain reliability. The more we write,
    the more we will have to write." [1, p344]

    "Aside from performance considerations, however, the principal reason to
    distrust defensive programming is simply our goal of getting the best
    possible reliability. For a system of any significant size the individual
    quality of the various elements involved is not enough; what will count most
    is the guarantee that for every interaction between two elements there is an
    explicit roster of mutual obligations and benefits - the contract. Hence the
    Zen-style paradox of our conclusion: that to get more reliability the best
    policy is often to check less." [1, p345]

    "Lew" <> wrote
    >The method [Math.sqrt] must handle the illegal input. No amount
    >of concern for "performance" relieves it of responsibility to
    >handle a negative input.
    >

    wow it is even scary! like the perfect example, hey! I will let Bertrand
    Meyer respond to you here ...

    "Such a comment, however, comes from a microscopic understanding of
    reliability, focused on individual software elements such as the sqrt
    routine. If we restrict our view to the narrow world of sqrt, then the
    routine seems more robust with the extra test than without it. But the world
    of a system is not restricted to a routine; it contains a multitude of
    routines in a multitude of classes. To obtain reliable systems we must go
    from the microscopic view to a macroscopic view encompassing the entire
    architecture." [1, p344]

    "Lew" <> wrote
    >According to you, that would never happen.
    >How do you guarantee that? What would the
    >result be?
    >

    "if the client's part of the contract is not fulfilled, that is to say if
    the call does not satisfy the precondition, then the class is not bound by
    the postcondition. In this case the routine may do what it pleases: return
    any value; loop indefinitely without returning a value; or even crash the
    execution in some wild way. This is the case in which (in reference to the
    discussion at the beginning of this chapter) 'the customer is wrong'." [1,
    p343]

    Once there is a programming error that lead to pre condition violations in
    production, it does not really matter what the preferred paradigm is, either
    DbC or Defensive Programming, the result will be either a crash or any
    behavior that differs to that stated in the software specification.

    An excellent example on how the defensive programming approach i.e. check
    and throw exception can not only give a very subjective sense of safety but
    also become "the problem" is the 500 million loss case of Ariane 5 "The
    exception was due to a floating-point error: a conversion from a 64-bit
    integer to a 16-bit signed integer, which should only have been applied to a
    number less than 2^15, was erroneously applied to a greater number,
    representing the "horizontal bias" of the flight. There was no explicit
    exception handler to catch the exception, so it followed the usual fate of
    uncaught exceptions and crashed the entire software, hence the on-board
    computers, hence the mission. " [4]

    From my professional experience I have personally seen and worked with both
    approaches. I have seen software developed for the Java platform that could
    not afford bugs but neither compromise in reliability nor performance, a
    real-time high-frequency trading arbitrage solution using the closest DbC
    you can have in Java. I can't recall one single e.g.
    IndexOutOfBoundsException in production and most pre condition verifications
    were done via asserts and these were only enabled during testing.

    I hope all the excerpts and explanations illustrate my point.

    "Lew" <> wrote
    >According to you, that would never happen.
    >How do you guarantee that? What would the
    >result be?
    >

    The group of SE at ETH Zurich works on several answers to these questions
    e.g.

    - Formal methods [5]
    - Contract-based automatic testing [6]

    Soon there is this very very nice and interesting LASER Summer School where
    Bertrand Meyer himself will present some of these concepts
    [http://se.inf.ethz.ch/laser/2009/index.php]. I might join btw

    For perfectjpattern I deliverately chose to stick to the way Sun commends
    regarding the use of assertions, I would like my project perfectjpattern to
    be accepted and not rejected by the Java community. I know the concepts of
    DbC and how implementing those concepts in Java via assertions might be
    outrageous for experienced developers (hey! at first it happened to me too)
    but it can't hurt to have a wider picture and use this knowledge to make
    more educated design decisions.

    Related discussions:

    "Where should I throw RuntimeException"
    [http://groups.google.com/group/comp...&lnk=gst&q=RuntimeException#30a419d1a0522e92]

    "Assertions vs Exceptions" posted to this group in 2007
    [http://groups.google.com/group/comp...read/54c528bd8ca61f73/e4ebf460a43f9aa1?hl=en]

    "Modular Protection vs Assertions" posted to the comp.lang.eiffel group in
    2007
    [http://groups.google.com/group/comp...fbf9cd89c5/273571d8d33088a1#273571d8d33088a1]

    Best regards,
    Giovanni

    [1] Programming with Assertions
    [http://java.sun.com/j2se/1.5.0/docs/guide/language/assert.html]
    [2] Object Oriented Software Construction 2nd Edition Bertrand Meyer
    [http://www.amazon.com/Object-Orient...sr_1_1?ie=UTF8&s=books&qid=1243672117&sr=8-1]
    [3] OOSC course slides "Design by Contract"
    [http://se.inf.ethz.ch/teaching/ss2005/0250/lectures/oosc_11_dbc_1up.pdf]
    [4] The lessons of Ariane
    [http://archive.eiffel.com/doc/manuals/technology/contract/ariane/page.html]
    [5] Formal methods [http://en.wikipedia.org/wiki/Formal_methods]
    [6] Automatic Testing based on Design by Contract
    [http://www.mathematik.uni-ulm.de/sai/mayer/soqua05/slides/ciupa.pdf]
    Giovanni Azua, May 30, 2009
    #1
    1. Advertising

  2. Giovanni Azua

    Roedy Green Guest

    The way I see it is this:

    Assertions are to defend against programming bugs.

    Exceptions are to defend against bad or freakish data.

    I think we programmers tend to underuse assertions. They can detect
    subtle problems before the bug shows up as obvious insane program
    behaviour. You can leave assertions in place without speed penalty by
    not using an -ea on the command line.

    --
    Roedy Green Canadian Mind Products
    http://mindprod.com

    "Everybody’s worried about stopping terrorism. Well, there’s a really easy way: stop participating in it."
    ~ Noam Chomsky
    Roedy Green, May 30, 2009
    #2
    1. Advertising

  3. Giovanni Azua wrote:
    [ SNIP ]

    > The point I was defending was that Sun's commended way to use assertions was
    > too categorical "Do not use assertions to check the parameters of a public
    > method" [2]. The reasoning for my discrepancy towards that rule is that
    > programs should not handle pre condition violations that are rooted in
    > programming errors by means of exceptions e.g. IllegalArgumentException.
    > However, the case of user input validation is a good use-case for using
    > IllegalArgumentException. In general, exceptions are meant to be handled
    > programmatically. You can't nor should recover from programming errors but
    > rather *fix* them e.g.
    >
    > Defensive alternative A:
    >
    > public void defensiveMethod(...) throws IllegalArgumentException {
    > // first checks
    > if (/* some input programming error condition */) {
    > throw IllegalArgumentException("Caught just another bug");
    > }
    >
    > // some checks
    > // some more checks ...
    >
    > // now we are "safe", do the real business
    > }
    >
    > // a possible client
    > try {
    > defensiveMethod(...);
    > }
    > catch (IllegalArgumentException exception) {
    > // what can you possibly do here? maybe we could ...
    > //
    > // - retrieve class name of the caller
    > // - get the author name out of the java file
    > // - send her an email complaining to FIX her code!
    > }
    >
    > vs.
    >
    > DbC alternative B:
    >
    > public void dbCMethod(...) {
    > // assert-based pre condition verification. Assertions
    > // will be disabled once all programming errors are
    > // corrected
    >
    > // assert-based class invariant verification
    >
    > // do the real business
    >
    > // assert-based class invariant verification
    >
    > // assert-based post-condition verification
    > }

    [ SNIP ]

    Giovanni, I have some problems with the above examples. Let me explain
    why. :)

    Leaving temporarily aside the issue of "defensive" (I prefer to call it
    "argument checking" in this case) code having errors, the main point I'd
    like to make is that defensiveMethod() does not have pre-conditions that
    could be addressed using asserts. It's *expected* that certain inputs
    will come in that we then screen out, using that "if", and tell the
    client that the input was unacceptable by throwing an
    IllegalArgumentException. In this scenario, that code is *not* error
    handling code (except in the widest sense, that of user input error
    perhaps), and it's certainly not a programming error to be discovered
    using assertions - it's business logic.

    As far as the "defensive" code itself having errors, as far as I am
    concerned go ahead and use assertions to help track those down if you
    wish. You could have an assert related to the condition used by the "if"
    if it made sense. I might add, if you're going to include stuff like
    that in contrasting examples, it would have been only fair to have

    assert (/* some egregiously wrong condition */);

    The main point I'm making is, there are errors and then there are
    errors. In the case of defensiveMethod() allowing for argument #2 to be
    a String, really wanting it to be a "\\d+", but sometimes seeing "\\w+",
    seeing a String that is not a "\\d+" is not a programming error. So why
    would we ever consider using assertions?

    AHS
    Arved Sandstrom, May 30, 2009
    #3
  4. Giovanni Azua wrote:
    > The point I was defending was that Sun's commended way to use assertions was
    > too categorical "Do not use assertions to check the parameters of a public
    > method" [2]. The reasoning for my discrepancy towards that rule is that
    > programs should not handle pre condition violations that are rooted in
    > programming errors by means of exceptions e.g. IllegalArgumentException.


    In the C and C++ world, such invalid parameters as null pointers can
    cause what could have been merely an operation to fail to cause the
    program to crash (the dreaded segfault). It is therefore very advisable
    in those languages to always defend methods against invalid parameters,
    even if it's programmer and not user error.

    In Java, of course, the uncaught IllegalArgumentException would do much
    the same thing that the analogous NullPointerException would have done.
    There is, however, one key difference: if you check the arguments at the
    beginning of the method, you prevent the class from entering an
    erroneous, incomplete state, which allows for the ability to merely
    consume the programmer error by simply invalidating the operation and
    allowing recoverability.

    > public void dbCMethod(...) {
    > // assert-based pre condition verification. Assertions
    > // will be disabled once all programming errors are
    > // corrected


    Given the history of software design, this should be interpreted as
    assertions will never be disabled. How can you know when you've fixed
    all programming errors? I'm willing to bet that even TeX still has
    errors in it, and that's a program whose maintenance is purely bug-fix
    these days.

    > Defensive programming as defined by Bertrand Meyer above yields the
    > following negative consequences in software engineering:
    >
    > - degrades performance


    An intelligent design will only have to check the arguments once per
    library level. Take a look at Java's Arrays' sort methods--instead of
    performing the recursive call with the public, argument-checking
    methods, all of the methods recursively call private, non-checking
    methods. In the end, all public methods are defensive yet the penalizing
    performance.

    Also, if defensive checks are seriously degrading performance, you're
    probably not doing them right.

    > Once there is a programming error that lead to pre condition violations in
    > production, it does not really matter what the preferred paradigm is, either
    > DbC or Defensive Programming, the result will be either a crash or any
    > behavior that differs to that stated in the software specification.


    The worst that can happen if preconditions are violated and the callee
    does not seek to adhere to any contract is that an exploit occurs--the
    leak of information to those not permitted to see it. The wast that can
    happen if the callee simply errors out immediately on violated
    preconditions is that an error is promulgated upwards. Whatever results
    come out of such a situation is entirely due to the unimaginative
    programmer who assured himself that his program could not error.

    > An excellent example on how the defensive programming approach i.e. check
    > and throw exception can not only give a very subjective sense of safety but
    > also become "the problem" is the 500 million loss case of Ariane 5 "The
    > exception was due to a floating-point error: a conversion from a 64-bit
    > integer to a 16-bit signed integer, which should only have been applied to a
    > number less than 2^15, was erroneously applied to a greater number,
    > representing the "horizontal bias" of the flight. There was no explicit
    > exception handler to catch the exception, so it followed the usual fate of
    > uncaught exceptions and crashed the entire software, hence the on-board
    > computers, hence the mission. " [4]


    This strikes me as a strong admission of support for checked exceptions,
    not an argument against checking conditions. What if there hadn't been a
    check, and the program had made the conversion as instructed? It seems
    to me that there would have been a variable storing the horizontal bias
    of the flight which was a few magnitudes of order off--which sounds like
    it would have resulted in the craft thinking it was somewhere else,
    ultimately crashing into an obstacle as a result of miscalculation.

    This is also a result of underappreciation for Murphy's Law.


    In the end, you have not convinced me of the harms of doing parameter
    validation via exceptions versus asserts. I would much rather be told
    that my method call failed via an exception, which permits me the
    ability to handle it, than I would that it blithely continues into a
    corrupt state.
    --
    Beware of bugs in the above code; I have only proved it correct, not
    tried it. -- Donald E. Knuth
    Joshua Cranmer, May 30, 2009
    #4
  5. In article <gvrjm8$m4u$>,
    Joshua Cranmer <> wrote:

    > Giovanni Azua wrote:

    [...]
    > > An excellent example on how the defensive programming approach i.e.
    > > check and throw exception can not only give a very subjective sense
    > > of safety but also become "the problem" is the 500 million loss
    > > case of Ariane 5 "The exception was due to a floating-point error:
    > > a conversion from a 64-bit integer to a 16-bit signed integer,
    > > which should only have been applied to a number less than 2^15, was
    > > erroneously applied to a greater number, representing the
    > > "horizontal bias" of the flight. There was no explicit exception
    > > handler to catch the exception, so it followed the usual fate of
    > > uncaught exceptions and crashed the entire software, hence the
    > > on-board computers, hence the mission. "

    >
    > This strikes me as a strong admission of support for checked
    > exceptions, not an argument against checking conditions.


    This is precisely correct. The claims made in the work cited [1] are
    subject to some debate [2]. The relevant exception was disabled in the
    Ariane 4 inertial reference system (IRS) for performance reasons [3].
    The IRS functioned correctly in Ariane 4 because the flight path
    characteristics precluded an incorrect value [4-3.1o]. The Araine 4 IRS
    was reused in the Araine 5 without adequate testing of the new flight
    parameters and without re-enabling the exception [4-3.1r,s].

    [...]

    [1]<http://archive.eiffel.com/doc/manuals/technology/contract/ariane/page.html>
    [2]<http://home.flash.net/~kennieg/ariane.html>
    [3]<http://en.wikipedia.org/wiki/Ariane_5_Flight_501>
    [4]<http://web.archive.org/web/20000815230639/www.esrin.esa.it/htdocs/tidc/Press/Press96/ariane5rep.html>
    --
    John B. Matthews
    trashgod at gmail dot com
    <http://sites.google.com/site/drjohnbmatthews>
    John B. Matthews, May 30, 2009
    #5
  6. Giovanni Azua

    Lew Guest

    John B. Matthews wrote:
    > In article <gvrjm8$m4u$>,
    > Joshua Cranmer <> wrote:
    >
    >> Giovanni Azua wrote:

    > [...]
    >>> An excellent example on how the defensive programming approach i.e.
    >>> check and throw exception can not only give a very subjective sense
    >>> of safety but also become "the problem" is the 500 million loss
    >>> case of Ariane 5 "The exception was due to a floating-point error:
    >>> a conversion from a 64-bit integer to a 16-bit signed integer,
    >>> which should only have been applied to a number less than 2^15, was
    >>> erroneously applied to a greater number, representing the
    >>> "horizontal bias" of the flight. There was no explicit exception
    >>> handler to catch the exception, so it followed the usual fate of
    >>> uncaught exceptions and crashed the entire software, hence the
    >>> on-board computers, hence the mission. "

    >> This strikes me as a strong admission of support for checked
    >> exceptions, not an argument against checking conditions.

    >
    > This is precisely correct. The claims made in the work cited [1] are
    > subject to some debate [2]. The relevant exception was disabled in the
    > Ariane 4 inertial reference system (IRS) for performance reasons [3].
    > The IRS functioned correctly in Ariane 4 because the flight path
    > characteristics precluded an incorrect value [4-3.1o]. The Araine 4 IRS
    > was reused in the Araine 5 without adequate testing of the new flight
    > parameters and without re-enabling the exception [4-3.1r,s].
    >
    > [...]
    >
    > [1]<http://archive.eiffel.com/doc/manuals/technology/contract/ariane/page.html>
    > [2]<http://home.flash.net/~kennieg/ariane.html>
    > [3]<http://en.wikipedia.org/wiki/Ariane_5_Flight_501>
    > [4]<http://web.archive.org/web/20000815230639/www.esrin.esa.it/htdocs/tidc/Press/Press96/ariane5rep.html>


    As the evidence mounts, the argument for "don't check input values" seems to
    rest on "Bertrand Meyer says so", and the counterargument to "you cannot
    prevent client code from handing in invalid values" is, "that's their
    problem". If a check is done in client code to prevent bad values, that's the
    same performance "penalty" as doing it in API code, but in the latter case the
    code cannot fail to perform as contracted, and the check is centralized in the
    logic that understands the preconditions.

    So despite the disparaging tone implied in the use of the term "defensive
    programming", the actual evidence and logic presented continue to support
    putting condition checks in the API methods, and thus allowing the method to
    deal sensibly with any given input, irrespective of error or mischief by
    client code.

    --
    Lew
    Lew, May 30, 2009
    #6
  7. Giovanni Azua

    Stefan Ram Guest

    "Giovanni Azua" <> writes:
    >- degrades performance


    I have two thoughts on this.

    1.) Assume »div(x,y)« had undefined behaviour when y == 0,
    and we wanted to do this in an application:

    for( x = 0; x < HUGE; ++x )div( x, y );

    The application knows that in the case of y being 0, the
    best thing to do is »f()«, so

    if( y )for( x = 0; x < HUGE; ++x )div( x, y ); else f();

    . We can see that it is sufficient to do the test /once
    outside of the loop/ for a primitive variable »y« in a
    single-threaded application. If the test would be done
    inside of »div« instead, it would not be possible to move
    it outside of the loop.

    2.) Assume »div(x,y)« had undefined behaviour when y == 0.
    One can always write a wrapper »defensiveDiv(x,y)« that has
    defined behaviour for y == 0 and otherwise the same behavior
    as »div(x,y)«, while it might be slower than »div(x,y)«.

    On the other hand, given only »defensiveDiv(x,y)« it is not
    possible to write a wrapper to get the behavior and run-time
    properties of »div(x,y)«.
    Stefan Ram, May 30, 2009
    #7
  8. Hallo Stefan,

    "Stefan Ram" <-berlin.de> wrote in message
    > I have two thoughts on this.
    >
    > 1.) Assume »div(x,y)« had undefined behaviour when y == 0,
    > and we wanted to do this in an application:
    >
    > for( x = 0; x < HUGE; ++x )div( x, y );
    >
    > The application knows that in the case of y being 0, the
    > best thing to do is »f()«, so
    >
    > if( y )for( x = 0; x < HUGE; ++x )div( x, y ); else f();
    >
    > . We can see that it is sufficient to do the test /once
    > outside of the loop/ for a primitive variable »y« in a
    > single-threaded application. If the test would be done
    > inside of »div« instead, it would not be possible to move
    > it outside of the loop.
    >
    > 2.) Assume »div(x,y)« had undefined behaviour when y == 0.
    > One can always write a wrapper »defensiveDiv(x,y)« that has
    > defined behaviour for y == 0 and otherwise the same behavior
    > as »div(x,y)«, while it might be slower than »div(x,y)«.
    >
    > On the other hand, given only »defensiveDiv(x,y)« it is not
    > possible to write a wrapper to get the behavior and run-time
    > properties of »div(x,y)«.
    >

    Good insight indeed, very nice!

    Gruss!
    Giovanni
    Giovanni Azua, May 30, 2009
    #8
  9. Giovanni Azua

    Lew Guest

    Stefan Ram wrote:
    >> I have two thoughts on this.
    >>
    >> 1.) Assume �div(x,y)� had undefined behaviour when y == 0,
    >> and we wanted to do this in an application:
    >>
    >> for( x = 0; x < HUGE; ++x )div( x, y );
    >>
    >> The application knows that in the case of y being 0, the
    >> best thing to do is �f()�, so
    >>
    >> if( y )for( x = 0; x < HUGE; ++x )div( x, y ); else f();
    >>
    >> . We can see that it is sufficient to do the test /once
    >> outside of the loop/ for a primitive variable �y� in a
    >> single-threaded application. If the test would be done
    >> inside of �div� instead, it would not be possible to move
    >> it outside of the loop.
    >>
    >> 2.) Assume �div(x,y)� had undefined behaviour when y == 0.
    >> One can always write a wrapper �defensiveDiv(x,y)� that has
    >> defined behaviour for y == 0 and otherwise the same behavior
    >> as �div(x,y)�, while it might be slower than �div(x,y)�.
    >>
    >> On the other hand, given only �defensiveDiv(x,y)� it is not
    >> possible to write a wrapper to get the behavior and run-time
    >> properties of �div(x,y)�.


    Giovanni Azua wrote:
    > Good insight indeed, very nice!


    In Java, if the arguments are integers then division by 0 with the '/'
    operator throws an 'ArithmeticException'. Is that "defensive programming"?
    Does it make the '/' operation slow?

    In Java, if the arguments are of a floating-point type, e.g., 'double', then
    division by zero yields a double value ('NaN' or signed infinity). Is that
    "defensive programming"? Does it make the '/' operation slow?

    It seems that Java is able to define arithmetic '/' such that it can handle
    all possible inputs without running into the performance problems that some
    seem to think are a risk. If one wants to modify the behavior of division by
    zero, say with integers to avoid causing an 'ArithmeticException', one can do
    the optimized value check that Stefan suggests. Presumably this would be
    inside a method that accepts a value for 'y' and forwards the action to 'f()'
    or '/' as needed. Is that "defensive programming", or is the check outside
    the loop for 'y == 0' and corresponding delegation to 'f()' just "good
    programming"?

    --
    Lew
    Lew, May 30, 2009
    #9
  10. On 30.05.2009 12:46, Giovanni Azua wrote:
    > Before moving into the concrete arguments I wanted to present the following
    > definitions by Bertrand Meyer:
    >
    > Defensive programming: "A technique of fighting potential errors by making
    > every module check for many possible consistency conditions, even if this
    > causes redundancy of checks performed by clients and suppliers. Contradicts
    > Design by Contract." [1, p1195]
    >
    > Design by Contract: "A method of software construction that designs the
    > components of a system so that they will cooperate on the basis of precisely
    > defined contracts. See also: defensive programming." [1, p1195]
    >
    > "Assertion Violation rule (1) A run-time assertion violation is the
    > manifestation of a bug in the software." [1, p346]
    >
    > The key in the defensive programming definition is "check". It doesn't
    > really matter what is done after encountering the problem either throwing
    > exceptions or programming an alternate way e.g. Math.sqrt that handles the
    > special case of negative input by returning Double.NaN. Please note that
    > neither Eiffel "require" nor the Java "assert" for verification of pre
    > conditions would fall under the category "check", by definition Design by
    > Contract (DbC) is not a check, they are enabled only optionally and for
    > discovering programming errors. Granted that Java assert feature is a small
    > subset of what Eiffel DbC offers [3, p15 "So, is it like 'assert.h'"].
    >
    > The point I was defending was that Sun's commended way to use assertions was
    > too categorical "Do not use assertions to check the parameters of a public
    > method" [2]. The reasoning for my discrepancy towards that rule is that
    > programs should not handle pre condition violations that are rooted in
    > programming errors by means of exceptions e.g. IllegalArgumentException.
    > However, the case of user input validation is a good use-case for using
    > IllegalArgumentException.


    Actually, if you write a library that is distributed as a jar the code
    must check input into public accessible methods always and handle them
    appropriately. This often means throwing an IllegalArgumentException
    but it may also mean returning a special value such as NaN. Which
    approach is more appropriate depends on the situation. But the code
    needs to do this in order to maintain integrity of its internal state
    (class invariants for example). Now, considering that a class is a
    module much the same way as library every public method of it is part of
    its API and marks the border between "outside" and "inside".

    Basically this means that all public and protected methods need some
    form of argument checking and dealing with illegal data. Other
    languages have other means but since Java does not support DbC in the
    language you have to use the features that you have.

    IMHO you should only use assert for input checking if a) performance is
    paramount _and_ b) you have _system_ test coverage that includes
    combinations of all classes of correct and incorrect input data and all
    possible invocation paths. This means that for most Java applications
    out there (which do not play in the field of space mission control or
    high performance realtime processing) you would rather have checks with
    exceptions than using assert for input checking.

    Personally I often use assert in situations where non trivial
    calculations are done and I would have used a comment in pre Java 5.
    The nice thing about assert is that you do not pay the performance
    penalty in production while retaining a relatively short expression
    which also helps documenting. For example

    Collection<Foo> foos = ...
    ... complex processing here which must eventually empty foos ..
    assert foos.isEmpty();

    > In general, exceptions are meant to be handled
    > programmatically. You can't nor should recover from programming errors but
    > rather *fix* them e.g.


    This is the precise reason why there are checked and unchecked
    exceptions in Java. Similarly to Error and subclasses unchecked
    exceptions should be handled programmatically only in relatively rare
    cases, e.g. in a testing framework or in an application which must keep
    running under all circumstances (e.g. a JEE container which must not
    break just because a single application of potentially many deployed
    applications runs berserk).

    > A few excerpts from Bertrand Meyer's book:
    >
    > "Non-Redundancy principle: Under no circumstances shall the body of a
    > routine ever test for the routine's precondition." [1, p343] For the example
    > that depicts such case he writes "is not just unnecessary but unacceptable"
    > [1, p343]


    You need to keep on mind that this is in the context of his book where
    he presents Eiffel. (Btw, it seems you got the quote numbering wrong,
    this must be from OOSC which is [2] in your posting.) With a language
    that provides rich DbC support and declarative pre- and postconditions
    it is of course nonsense to check those inside method bodies.

    > "Aside from performance considerations, however, the principal reason to
    > distrust defensive programming is simply our goal of getting the best
    > possible reliability. For a system of any significant size the individual
    > quality of the various elements involved is not enough; what will count most
    > is the guarantee that for every interaction between two elements there is an
    > explicit roster of mutual obligations and benefits - the contract. Hence the
    > Zen-style paradox of our conclusion: that to get more reliability the best
    > policy is often to check less." [1, p345]


    This still means that you need _some_ form of automatic checking of this
    contract so you can detect violations. _How_ this checking is done is a
    highly programming language dependent issue. In Eiffel you have DbC
    support, in Java you have assert, checks and exceptions.

    > "Lew" <> wrote
    >> The method [Math.sqrt] must handle the illegal input. No amount
    >> of concern for "performance" relieves it of responsibility to
    >> handle a negative input.


    > "Such a comment, however, comes from a microscopic understanding of
    > reliability, focused on individual software elements such as the sqrt
    > routine. If we restrict our view to the narrow world of sqrt, then the
    > routine seems more robust with the extra test than without it. But the world
    > of a system is not restricted to a routine; it contains a multitude of
    > routines in a multitude of classes. To obtain reliable systems we must go
    > from the microscopic view to a macroscopic view encompassing the entire
    > architecture." [1, p344]


    I can agree to that one although I find the statement very vague. And:
    looking at the entire architecture does not make Lew's point invalid
    that your microscopic checks need to be there - one way or another. You
    cannot build a house on individual components that do not deliver
    advertised quality.

    > I hope all the excerpts and explanations illustrate my point.


    Frankly, with all the quotes I am not sure what _your_ point really is.
    You seem to advocate to drop what has been called "defensive
    programming" in your article but since I did not follow the other thread
    my insights into your own reasoning are limited.

    Kind regards

    robert

    --
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
    Robert Klemme, May 31, 2009
    #10
  11. "Giovanni Azua" <> wrote in message
    > [1] Programming with Assertions
    > [http://java.sun.com/j2se/1.5.0/docs/guide/language/assert.html]
    > [2] Object Oriented Software Construction 2nd Edition Bertrand Meyer
    > [http://www.amazon.com/Object-Orient...sr_1_1?ie=UTF8&s=books&qid=1243672117&sr=8-1]
    >

    I made a mistake in the order of these two references, it should be:

    [1] Object Oriented Software Construction 2nd Edition Bertrand Meyer
    http://www.amazon.com/Object-Orient...=sr_1_1?ie=UTF8&s=books&qid=1243672117&sr=8-1
    [2] Programming with Assertions
    http://java.sun.com/j2se/1.5.0/docs/guide/language/assert.html

    Best regards,
    Giovanni
    Giovanni Azua, May 31, 2009
    #11
  12. Hello Robert,

    Please find my comments below:

    "Robert Klemme" <> wrote in message
    > Actually, if you write a library that is distributed as a jar the code
    > must check input into public accessible methods always and handle them
    > appropriately. This often means throwing an IllegalArgumentException
    > [snip]
    >

    I don't agree that the type of distribution source, jar, war or ear is what
    drives the decision to label public methods as "exposed". I explain at the
    end.

    >> A few excerpts from Bertrand Meyer's book:
    >>
    >> "Non-Redundancy principle: Under no circumstances shall the body of a
    >> routine ever test for the routine's precondition." [1, p343] For the
    >> example that depicts such case he writes "is not just unnecessary but
    >> unacceptable" [1, p343]

    >
    > You need to keep on mind that this is in the context of his book where he
    > presents Eiffel. [snip] With a language that provides rich DbC support
    > and declarative pre- and postconditions it is of course nonsense to check
    > those inside method bodies.
    >

    In principle I agree with you, asserts are not a full fledge DbC
    implementation, but for the OP being discussed: pre condition verification
    you can get quite a good approximation with the assert construct.

    >> "Aside from performance considerations, however, the principal reason to
    >> distrust defensive programming is simply our goal of getting the best
    >> possible reliability. For a system of any significant size the individual
    >> quality of the various elements involved is not enough; what will count
    >> most is the guarantee that for every interaction between two elements
    >> there is an explicit roster of mutual obligations and benefits - the
    >> contract. Hence the Zen-style paradox of our conclusion: that to get more
    >> reliability the best policy is often to check less." [1, p345]

    >
    > This still means that you need _some_ form of automatic checking of this
    > contract so you can detect violations. _How_ this checking is done is a
    > highly programming language dependent issue. In Eiffel you have DbC
    > support, in Java you have assert, checks and exceptions.
    >

    You only need to build sufficient test suites with test coverage
    proportional to the cyclomatic complexity.

    >> "Lew" <> wrote
    >>> The method [Math.sqrt] must handle the illegal input. No amount
    >>> of concern for "performance" relieves it of responsibility to
    >>> handle a negative input.

    >
    >> "Such a comment, however, comes from a microscopic understanding of
    >> reliability, focused on individual software elements such as the sqrt
    >> routine. If we restrict our view to the narrow world of sqrt, then the
    >> routine seems more robust with the extra test than without it. But the
    >> world of a system is not restricted to a routine; it contains a multitude
    >> of routines in a multitude of classes. To obtain reliable systems we must
    >> go from the microscopic view to a macroscopic view encompassing the
    >> entire architecture." [1, p344]

    >
    > I can agree to that one although I find the statement very vague.

    Good that we agree here. Why is it vague?

    > And: looking at the entire architecture does not make Lew's point invalid
    > that your microscopic checks need to be there - one way or another. You
    > cannot build a house on individual components that do not deliver
    > advertised quality.
    >

    The microscopic view of reliability comes from the fact that every method in
    every class would have unnecsessary defensive checks, I think the means
    defeats the purpose in this case.

    > Frankly, with all the quotes I am not sure what _your_ point really is.
    > You seem to advocate to drop what has been called "defensive programming"
    > in your article but since I did not follow the other thread my insights
    > into your own reasoning are limited.
    >

    My point is the following:

    > On 30.05.2009 12:46, Giovanni Azua wrote:
    >> The point I was defending was that Sun's commended way to use assertions
    >> was too categorical "Do not use assertions to check the parameters of a
    >> public method" [2]. The reasoning for my discrepancy towards that rule is
    >> that ...


    I believe that the best rule to decide whether to place validation in a
    public method should depend on the concept of "exposed" rather than the
    access level alone:

    - If the public method is "exposed" then use "defensive programming"
    integrity checks [1, p1195]
    - If the public method is not "exposed" then use assertions or DbC

    Examples of "exposed" public methods:

    - Method exposed as Web Service
    - Method exposed as business EJB
    - Method that reads input from file
    - Method that reads from a Socket
    - Method that processes end user gestures and inputs, "filtering" layer [1]
    after a presentation layer

    Example of non "exposed" public methods:

    - JPA API
    - XML API
    - Utilities API
    - JDK Collections API
    - JDK Concurrency API
    - Java Arrays
    - Design patterns library

    What do all non "exposed" public methods have in common? that any Java
    application or component built on top of them can proof fulfillment of pre
    condition and correctness via unit testing while assertions are enabled i.e.
    any pre condition violation is a programming error whereas the case of
    "exposed" public methods the possible pre conditions violations can not be
    unit tested/prevented and require input validation.

    Again to conclude, my only point here is that the statement "Do not use
    assertions to check the parameters of a public method" [2] is too
    categorical and not the absolute truth.

    Best regards,
    Giovanni
    Giovanni Azua, May 31, 2009
    #12
  13. "Lew" <> wrote in message
    > In Java, if the arguments are integers then division by 0 with the '/'
    > operator throws an 'ArithmeticException'. Is that "defensive
    > programming"? Does it make the '/' operation slow?
    >
    > In Java, if the arguments are of a floating-point type, e.g., 'double',
    > then division by zero yields a double value ('NaN' or signed infinity).
    > Is that "defensive programming"? Does it make the '/' operation slow?
    >

    This is what Bertrand Meyer calls the microscopic view of reliability ... I
    provided the reasoning and explanations in the OP and not just the "Bertrand
    Meyer says so" argument that you presented before.

    > It seems that Java is able to define arithmetic '/' such that it can
    > handle all possible inputs without running into the performance problems
    > that some seem to think are a risk.

    I don't think this was the point that Stefan was trying to make.

    > If one wants to modify the behavior of division by zero, say with integers
    > to avoid causing an 'ArithmeticException', one can do the optimized value
    > check that Stefan suggests. Presumably this would be inside a method that
    > accepts a value for 'y' and forwards the action to 'f()' or '/' as needed.
    > Is that "defensive programming", or is the check outside the loop for 'y
    > == 0' and corresponding delegation to 'f()' just "good programming"?
    >

    I think it depends, if that supposed method would be "exposed" e.g. a method
    exposed as Web Service then the input validation rule applies, it would then
    be "good defensive programming". If, on the other hand, the supposed method
    belongs to an Utils/Support API e.g. Math then I would use assertions rather
    than defensive checks.

    It is unlikely that someone develops a professional UI that would let users
    enter values that are passed directly to Utils/Supports API or primitive
    operator calls e.g. "a / b" that would be a very bad design. In this case as
    I mentioned before you would have a presentation layer (input conditional
    checking) or enforced by the UI widgets e.g. combo boxes rather than input
    fields, then the defensive filter layer [1] and finally the call to the
    assert-based f(a,b) = "a / b".

    I would be curious to know what your handler would look like for an
    'ArithmeticException', maybe I will learn something new today, and I mean it
    without any bad intentions. I think any piece of code leading to an
    'ArithmeticException' will need to be reviewed, fixed and better unit
    tested.

    Best regards,
    Giovanni
    Giovanni Azua, May 31, 2009
    #13
  14. Giovanni Azua wrote:
    [ SNIP ]

    > Again to conclude, my only point here is that the statement "Do not use
    > assertions to check the parameters of a public method" [2] is too
    > categorical and not the absolute truth.
    >
    > Best regards,
    > Giovanni


    It probably is too categorical, sure. I'll agree with that. I'll also
    agree that not all public methods are used in the same way - as you put
    it, some are "exposed" and some are not.

    My original post in this thread had to do specifically with what you
    call "exposed" public methods.

    Now, if we're talking preconditions, this is a client obligation. So if
    a non-"exposed" public method is not to do input checking, we'll expect
    all client code to do so instead. So just prior to calling that method
    from the client code we could certainly use assertions, since at that
    point we consider calling the method with incorrect arguments to be a
    programming error. I don't myself have any major problem with that, and
    I believe this is what you've been suggesting...correct me if I'm wrong.

    The only sticking point is, you'd want to be really careful with API
    design _and_ implementation. Lots of commenting also. Because clients
    would definitely want to know that if using such-and-such a method it's
    all up to them, and if they don't do the right thing the code is going
    to break badly.

    AHS
    Arved Sandstrom, May 31, 2009
    #14
  15. Hi Joshua,

    This is only a pre-response :) my gf is pushing me to leave the computer :)

    "Joshua Cranmer" <> wrote in message
    >
    > This strikes me as a strong admission of support for checked exceptions,
    > not an argument against checking conditions. What if there hadn't been a

    You really want to see a floor full of developers all complaining big time
    .... give them an API full of checked exceptions to work with! it is
    hilarious! :) I had once the chance to see this :)

    It is a bit contradictory because IllegalArgumentException would then be a
    good candidate for checked exception. But this won't happen unless Sun wants
    to see most of its fans moving to .Net :)

    Best regards,
    Giovanni
    Giovanni Azua, May 31, 2009
    #15
  16. Giovanni Azua

    Lew Guest

    Giovanni Azua wrote:
    > You really want to see a floor full of developers all complaining big time
    > ... give them an API full of checked exceptions to work with! it is
    > hilarious! :) I had once the chance to see this :)


    Obviously they didn't understand the value or purpose of checked exceptions.

    There really is nothing hilarious about ignorance. Checked exceptions are
    there for a good reason, and users of libraries that have checked exceptions
    in the method signature should focus on that. How much extra work is it to
    add ten lines of code to check an exception? Negligible, that's how much.
    What's to complain about? Especially considering that you get
    compiler-enforced reminders to handle the exceptions, so you don't even risk
    forgetting to handle them?

    --
    Lew
    Lew, May 31, 2009
    #16
  17. Giovanni Azua

    Lew Guest

    Giovanni Azua wrote:
    > I think it depends, if that supposed method would be "exposed" e.g. a method
    > exposed as Web Service then the input validation rule applies, it would then
    > be "good defensive programming". If, on the other hand, the supposed method
    > belongs to an Utils/Support API e.g. Math then I would use assertions rather
    > than defensive checks.


    Assertions are not a replacement or substitute for "defensive" checks, but
    complementary to them.

    > It is unlikely that someone develops a professional UI that would let users
    > enter values that are passed directly to Utils/Supports API or primitive
    > operator calls e.g. "a / b" that would be a very bad design. In this case as
    > I mentioned before you would have a presentation layer (input conditional
    > checking) or enforced by the UI widgets e.g. combo boxes rather than input
    > fields, then the defensive filter layer [1] and finally the call to the
    > assert-based f(a,b) = "a / b".


    I think we agree on this. You are making essentially the same point I've been
    making.

    I do think that you're glossing over the fact that the division operator also
    adheres to what I have been suggesting - it throws 'ArithmeticException' when
    you attempt integral division by zero, and returns a valid value when you
    attempt floating-point division by zero. So even if you let the input value
    from the presentation layer directly through to the division, division by zero
    gets handled. This is consistent with my recommendation and that of others,
    that all inputs should be handled.

    > I would be curious to know what your handler would look like for an
    > 'ArithmeticException', maybe I will learn something new today, and I mean it
    > without any bad intentions. I think any piece of code leading to an
    > 'ArithmeticException' will need to be reviewed, fixed and better unit
    > tested.


    Again I agree with you. As for my handler, it would depend on the desired
    product behavior. It might look like this:

    public int sumDivByInput( int divisor )
    {
    if ( divisor == 0 )
    {
    return 0;
    }
    assert divisor != 0;
    int sum = 0;
    for ( int divid : dividends )
    {
    sum += divid / divisor;
    }
    return sum;
    }

    --
    Lew
    Lew, May 31, 2009
    #17
  18. Giovanni Azua

    Lew Guest

    Giovanni Azua wrote:
    > I don't agree that the type of distribution source, jar, war or ear is what
    > drives the decision to label public methods as "exposed". I explain at the
    > end.

    ....
    > What do all non "exposed" public methods have in common? that any Java
    > application or component built on top of them can proof fulfillment of pre
    > condition and correctness via unit testing while assertions are enabled i.e.
    > any pre condition violation is a programming error whereas the case of
    > "exposed" public methods the possible pre conditions violations can not be
    > unit tested/prevented and require input validation.


    Once you release a class with public or protected methods, those methods are
    exposed. That's a fact. It is true as you say that the type of distribution
    is not relevant; the mere fact that a method is public or protected is what
    exposes it.

    > Again to conclude, my only point here is that the statement "Do not use
    > assertions to check the parameters of a public method" [2] is too
    > categorical and not the absolute truth.


    Actually, you have said nothing to contradict its truth, other than "it's not
    the absolute truth". Your suggestion to use assertions to aid in testing then
    to disable them supports the dictum not to use assertions to check the
    parameters of a public method, at least not in production contexts. You also
    recommend in such cases not to use exceptions or other so-called "defensive"
    mechanisms. If anything, you extend Sun's advice rather than contradict it;
    you go beyond "don't use assertions to check the parameters of a public
    method" to "don't use anything (in production) to check the parameters of a
    public method".

    Sun's point is true on the face of it - if you disable assertions, then they
    cannot check anything. so anyone relying on them for so-called "defensive"
    checks will be disappointed. That's all they're saying.

    --
    Lew
    Lew, May 31, 2009
    #18
  19. Giovanni Azua

    Tom Anderson Guest

    On Sat, 30 May 2009, John B. Matthews wrote:

    > In article <gvrjm8$m4u$>,
    > Joshua Cranmer <> wrote:
    >
    >> Giovanni Azua wrote:

    > [...]
    >>> An excellent example on how the defensive programming approach i.e.
    >>> check and throw exception can not only give a very subjective sense
    >>> of safety but also become "the problem" is the 500 million loss
    >>> case of Ariane 5 "The exception was due to a floating-point error:
    >>> a conversion from a 64-bit integer to a 16-bit signed integer,
    >>> which should only have been applied to a number less than 2^15, was
    >>> erroneously applied to a greater number, representing the
    >>> "horizontal bias" of the flight. There was no explicit exception
    >>> handler to catch the exception, so it followed the usual fate of
    >>> uncaught exceptions and crashed the entire software, hence the
    >>> on-board computers, hence the mission. "

    >>
    >> This strikes me as a strong admission of support for checked
    >> exceptions, not an argument against checking conditions.

    >
    > This is precisely correct. The claims made in the work cited [1] are
    > subject to some debate [2].


    That Eiffeltard article you link to makes my blood boil.

    There's only one thing that would have been guaranteed to catch the error,
    and all other kinds of error like it. It's not a funky language, or
    self-flagellating development practice, or esoteric philosophy. It's a lot
    simpler than that: it's testing.

    At no point before the 501 launch did the engineers perform a whole-system
    integration test. They never put the whole software package together on a
    testbed and see if it worked.

    The report spends some time sort of mumbling about why that would have
    been really hard and not really practical, but it's self-serving bullshit.
    You don't fly a billion euros of hardware that thousands of people have
    spent years of their lives building unless you've tested the software to
    that level. And if you can't figure out how to do that test, resign, and
    we'll find someone who can.

    If they had tested the complete system, they would have detected the
    problem after 37 seconds. No ifs, no buts.

    tom

    --
    build the roof with holes in
    Tom Anderson, May 31, 2009
    #19
  20. Hello Arved,

    "Arved Sandstrom" <> wrote in message
    > Now, if we're talking preconditions, this is a client obligation. So if a
    > non-"exposed" public method is not to do input checking, we'll expect all
    > client code to do so instead. So just prior to calling that method from
    > the client code we could certainly use assertions, since at that point we
    > consider calling the method with incorrect arguments to be a programming
    > error. I don't myself have any major problem with that, and I believe this
    > is what you've been suggesting...correct me if I'm wrong.
    >

    The assertions for pre condition verification would be on the routine
    supplier side and not on the client side. The real client (there could be
    more than one layer away) can either check for the input to be valid or make
    sure it is.

    > The only sticking point is, you'd want to be really careful with API
    > design _and_ implementation. Lots of commenting also. Because clients

    This is a good one. Unlike Eiffel and I think unfortunately the only way in
    Java to have a routine supplier explicitly advertising its pre conditions is
    through Javadoc and this is a flaw, because the Javadoc would need to be
    kept in sync with the asserts manually.

    There are several products that offer a proper DbC implementation in Java
    e.g.
    http://www.contract4j.org/contract4j
    http://www.mmsindia.com/JMSAssert.html

    The contract4j looks very nice actually (using annotations and aspects) but
    I can't tell how popular or widely adopted these are specially because I
    would not be surprised to see Sun adding support in Java for a full fledged
    DbC implementation in the future, anyone knows? :) Therefore having a
    codebase implementing DbC based on one of those solutions would mean to
    secure yourself a future migration problem.

    > would definitely want to know that if using such-and-such a method it's
    > all up to them, and if they don't do the right thing the code is going to
    > break badly.
    >

    Throwing an exception that no one will ever handle e.g.
    'ArithmeticException' will also lead to a break. I can't tell which one
    would be more badly though :) I believe that being less paranoid and keeping
    the code simpler without so much of the "defensive" would also be a good
    thing.

    Best regards,
    Giovanni
    Giovanni Azua, May 31, 2009
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    1
    Views:
    360
    Roedy Green
    Aug 14, 2003
  2. Robert Brewer
    Replies:
    1
    Views:
    480
    bsmith
    Nov 7, 2004
  3. Thomas Guettler

    assert 0, "foo" vs. assert(0, "foo")

    Thomas Guettler, Feb 23, 2005, in forum: Python
    Replies:
    3
    Views:
    2,502
    Carl Banks
    Feb 23, 2005
  4. Alex Vinokur

    assert(x) and '#define ASSERT(x) assert(x)'

    Alex Vinokur, Nov 25, 2004, in forum: C Programming
    Replies:
    5
    Views:
    897
    Keith Thompson
    Nov 25, 2004
  5. ImpalerCore

    To assert or not to assert...

    ImpalerCore, Apr 27, 2010, in forum: C Programming
    Replies:
    79
    Views:
    1,636
    Richard Bos
    May 17, 2010
Loading...

Share This Page