Article View: comp.lang.eiffel
Article #1110Re: [++] Re: Pure OO-What differentiates a true OO from object-based systems
From: Scott Wheeler
Date: Tue, 19 Dec 1995 18:10
Date: Tue, 19 Dec 1995 18:10
111 lines
4239 bytes
4239 bytes
In Article <4an3i4$43f@news.irisa.fr> Jean-Marc Jezequel writes:
>I basically agree with you but IMHO, the most important "bells and
>whistles" to the Design by Contract idea in Eiffel is that assertions
>are inherited by subclasses. That way you can constrain the
>implementor of an abstract (i.e. deferred, pure virtual) method to
>meet the requirements specified in its contract.
Agreed. BTW, looking back on my posting, I regret to say I was
indulging in my favourite vice of didacticising. I used to be a
teacher and I can't quite get out of the habit of explaining things
interminably.
>This is where I find the assert.h package too much limited in C and
>C++. If someone has an idea on how to emulate this mechanism in C++,
>I'm a taker.
The problem comes in doing it efficiently and cleanly. I'd approach it
by writing a pre-processor to generate C++ code from an extended
version of the language.
[Avert your eyes here, all CS students of impressionable age. Untested
code ahead. The following is only a basis for further discussion]
Let's say the starting version was this
== Extended C++ =====
class foo : public baz, quum
{
public :
virtual int myfunc(int a) :
pre { a>0; a<99 },
post { result>42 };
private :
int myvar;
invariant :
myvar>0;
myvar<6*7;
};
And suppose the generated version was this:
== Generated C++ =====
class foo : public baz
{
private :
typedef parent_1 baz;
typedef parent_2 quum;
public :
virtual int myfunc(int a)
protected :
int myfunc_pre(int a) const { return (a>0) && (a<99); }
int myfunc_post(int result) const { return result>42; }
int invariant() const;
}
int foo::myfunc(int a)
{
// This is just a wrapper around the real function
// check preconditions
assert(myfunc_pre(a) ||
(parent_1::myfunc_pre(a) && parent_2::myfunc_pre(a)));
// This is a publicly accessible function, so check the invariant
assert(invariant());
// call the real function
int result = myfunc_core(); // the user defines this
// check the invariant again.
assert(invariant());
// check postconditions
assert(myfunc_post(result) &&
(parent_1::myfunc_pre(a) && parent_2::myfunc_pre(a)));
}
int foo::invariant()
{
return (myvar<6*7) &&
(parent_1::invariant() && parent_2::invariant());
}
== Handwave ends ====
This doesn't look too difficult, depending on how much syntax checking
you want the preprocessor to do. It does need to know that in this case
both the baz and quum parent classes define myfunc(), otherwise the
checks of the pre- and post-conditions of the parent would be omitted.
I've done something similar for a different application with some awk
scripts, dumping the required information in auxiliary files. The
difficulty might be in controlling the order of precompilation,
particularly with pairs of classes like:
class foo;
class baz : public foo { ... };
class foo { ... }
Efficiency is not amazingly good, either - there will be redundant
calls of invariant() when one publicly visible function calls another.
This could be largely eliminated, but at the cost of a preprocessor
which understood much more about the language and was correspondingly
hard to implement.
The approach would also need some means of switching off checks at
different security levels, but this is probably not a major problem.
Scott
Technical Details
Message-ID:
<jzvudu@bmtech.demon.co.uk>Path:
arc1-ca.pugleaf.net!mail2news.demon.co.uk!bmtech.demon.co.ukReferences:
<139@feiffel.UUCP> <DJGqqr.M77@cix.compulink.co.uk> <jzuqcm@bmtech.demon.co.uk> <4an3i4$43f@news.irisa.fr>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!mail2news.demon.co.uk!bmtech.demon.co.uk From: Scott Wheeler <scottw@bmtech.demon.co.uk> Newsgroups: comp.lang.eiffel,comp.lang.c++ Subject: Re: [++] Re: Pure OO-What differentiates a true OO from object-based systems Followup-To: comp.lang.eiffel,comp.lang.c++ Date: Tue, 19 Dec 1995 18:10:20 +0000 Organization: British Maritime Technology Message-ID: <jzvudu@bmtech.demon.co.uk> References: <139@feiffel.UUCP> <DJGqqr.M77@cix.compulink.co.uk> <jzuqcm@bmtech.demon.co.uk> <4an3i4$43f@news.irisa.fr> Reply-To: Scott Wheeler <scottw@bmtech.demon.co.uk> X-NNTP-Posting-Host: bmtech.demon.co.uk X-Newsreader: NewsBase v1.36 (Beta) X-Mail2News-Path: relay-4.mail.demon.net!post.demon.co.uk!bmtech.demon.co.uk