Re: Cpp Considered Harmful

From: Chris F Clark (cfc_at_shell01.TheWorld.com)
Date: 08/31/04


Date: 31 Aug 2004 12:36:21 -0400

Steven T. Hatton talking about assertions (via cpp) wrote:

> There has to be some need I have before I look for something to fill
> it. The idea of aborting a program on failure is simply not
> something I believe to be a good practice.

Who says assertions have to abort your program? The assertions in our
code invoke a program specific interactive debugger that allows us to
trace what is going on at the level of user (and developer) visible
objects. Thus, if there is a problem connecting a "net" to a "gate"
via a "pin" (our code is used for circuit design) and an assertion
fires, the developer can inspect (graphically) the net, gate, and pin
and look at the diagram or user written source code that is involved,
and if necessary inspect the internal structure of each of the objects
(or look at other connected objects). The developer can also escape
into the normal C++ debugger if necessary. et cetera, et cetera, et
cetera.... And perhaps, most importantly, we can decide which
assertions represent errors that users can make (i.e. connecting a net
so that the net has two different drivers, which makes the net an
invalid circuit) or one that results from something unexpected
happening in the code (finding a net without any drivers after all the
nets have been checked to assure that they all have exactly one
driver), which means the code has some undetected flaw in it that
caused bad data to reach the point in question (or perhaps the code at
the current point is wrong).

Note, that nowhere did I say that our assertions abort the execution
of the program--assertions tell you where something went wrong, a good
assertion package helps you debug that point--a poor assertion
paqckage simply "gives up" (with a message) at the point where the
code failed--however, even that is better than the code randomly doing
something further wrong and possibly silently producing incorrect
results or mysteriously crashing in some unrelated part of the
program.

However, in either case, assertions are invaluable in making certain
that the code does exactly what we say it does and that flaws are
caught as near to the source of the error as possible. As a result,
the team has been amazingly productive. It has really paid off in the
maintenance/enhacement phase, where we can quickly upgrade or change
the semantics of various pieces knowing that if we violate any
downstream assumptions, those problems will be caught by the developer
before finishing coding, "unit" testing, and checking in. If you
don't use assertions, your programs probably continue to do bad things
in the sections you haven't well tested and you have to infer the
problem from the tea-leaves at the point where you finally figure out
the the program has done something wrong (like crashed)--that doesn't
work so well on a 600K line program, where there are huge blocks of
code you have never read much less understand or wrote.

Now, to bring this back to the cpp. Our assertion code is a set of
cpp macros. Originally, they were just the macros supplied by the C++
compiler. However, because that C++ assertion support was written as
cpp macros, when we realized that we wanted something more
sophisticated than what our C++ vendor provided, we were able to
customize it for ourselves. Moreover, because we now have our own cpp
macros, we can use several different compilers and have our system
work the same way. (And, yes, just like the XERCES code you were
complaining about, not all of our target compilers are "modern" so we
have some macros that deal with broken compilers that we are REQUIRED
to support.)

(This by the way is a flaw in JAVA. If I go to a web-site that has
JAVA that is poorly written and only works with one version of the
spec and that isn't the version installed on my machine, the web-site
is broken. What does one do when one has two different web sites,
that both require different versions of the spec? In C++ the web site
author can write his code to be compatible not only with the newest
spec, but also with older versions (perhaps with less functionality),
so that the user can pick an old version of the compiler and have all
the code be happy--maybe not as "fancy" as one would like, but
working! BTW, I experience this problem on a daily basis, as I have
tow web sites that I need to visit and they use incompatible JAVA
versions. I have two machines so that I can work around that
problem.)

And, what is the beauty of those macros (besides their portability),
is that our primary source code (the uses of those macros) is easy to
read. The syntax of the assert (and other macros) is quite simple and
obvious. That is only doable because they are macros. If they
weren't macros, some of the behind-the-scene-stuff like determining
the current object would have to be present in the source code of each
use. Without cpp, either the source code (at assertion use) would
have to be much uglier or the "assertion support" would have to be
built into the compiler. And if the assertion support were built into
the compiler, we would only get what the C++ compiler vendor provided
us, which would probably be a poor assertion package on most
platforms. Also note that the sophistication of our assertion support
has grown with our code. If it wasn't done via macros, the
behind-the-scenes stuff that cpp hides would have to have been changed
at every assertion use when we realized that the was "a better way" to
do things, as we have numerous times. In a language without cpp, we
simply wouldn't have bothered to do it, and we wouldn't have been
nearly as productive as a result.

So, that's the beauty of cpp, it lets one write simple obvious code
and put behind it something sophisticated that makes the code do the
right thing. It lets one do that in a compiler independent manner and
do so even in the pressence of seriously broken compilers. And, it
lets us "the application developers" do it and does not make us
dependent on our compiler vendors.

Oh, and by the way, I think that by "cleverly" using function
prototypes that match our macros, we get nice code completion of the
macros in our IDE--the best of both worlds.

Note, somewhere you wrote that you can do some of the same things with
sed and make. If you don't like cpp, why would you want to impose an
external macro processor (that's what you are using sed for in that
scenario) on your code? At least with cpp, you can know that you have
something that is portable. For the longest time, I used systems that
didn't even have sed on them. I may still do so. I don't know. It
isn't something I would use. Moreover, with sed macros, your IDE has
no hope of knowing exactly how your code will be transformed before
being compiled. That is much worse than cpp. (I can just imagine how
our development environment would be obscure if to get assertions, we
had to preprocess all our code with sed scripts. Wouldn't that be a
joy???)

-Chris

*****************************************************************************
Chris Clark Internet : compres@world.std.com
Compiler Resources, Inc. Web Site : http://world.std.com/~compres
23 Bailey Rd voice : (508) 435-5016
Berlin, MA 01503 USA fax : (978) 838-0263 (24 hours)
------------------------------------------------------------------------------



Relevant Pages

  • Re: Cpp Considered Harmful
    ... > However, in either case, assertions are invaluable in making certain ... because we now have our own cpp ... > macros, we can use several different compilers and have our system ... > built into the compiler. ...
    (comp.lang.cpp)
  • Re: C to Java Byte Code
    ... > Your assertion seems to be that the claim that 'a C to bytecode compiler ... No, that would be your assertion, since I never said or implied it anywhere. ... you would realize the burden of evidence is on the ... without human intervention and produce a Java program from some reasonable ...
    (comp.programming)
  • Re: Personal Rexx (Quercus) or what?
    ... didn't support INTERPRET. ... So what are the programmers at his shop, ... and if the compiler didn't support it, ... He then made an assertion that was untrue. ...
    (comp.lang.rexx)
  • Re: A question related to type casting
    ... So only if the specification specifically describes this as allowable would this be something we might expect to see from the JIT compiler.", and i stand by that - that assertion was simply and patently false. ... I realize that's not a proof, but at the same time I haven't seen any suggestion as to how a compiler can make a value type look reliably like a reference type without it actually being a reference type, without incurring some additional overhead in the code that manages that data, and the code that generates that code. ... public Class getClass() { ...
    (comp.lang.java.programmer)
  • Re: [Lit.] Buffer overruns
    ... > Karl Malbrain wrote: ... >> could use more help from a compiler. ... > Constructive Type Theory offers far more safety. ... how superior it is to an ASSERTION based method that C supports? ...
    (sci.crypt)