Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > function prototype / method declaration enhancement - assertions

Reply
Thread Tools

function prototype / method declaration enhancement - assertions

 
 
Bhushit Joshipura
Guest
Posts: n/a
 
      01-05-2004
I would like to gather views about an enhancement in C and C++ that
can lead to more robust programming.

First things first:
1. This posting addresses to both, C and C++. Please map an example to
your language of concern if it does not belong to your language of
concern.
2. Whatever I write here is a clear syntax error in both the
languages.

Pre-conditions and post-conditions to a function (method) are not only
important to theory or to comment inside code. They reflect in terms
of assert statements also. I propose to formalize them with prototype
/ declaration.

The idea:

1. Extend the concept of declaration (prototype) to a step further -
alongwith parameters, we specify assertions about them too. When the
function gets called (method gets invoked) these assertions, if
present, are [optionally] invoked before hitting the body of the
function.

For example, in C,

Current declaration:
int f ( int i, int *j, int k);

Possible extension 1:
int f (
int i {
i > 0 && i < INT_MAX
},
int *j {
j != NULL
},
int k {
k != some_global
}
);

2. Extend the concept of declaration to one more step further - we let
users add one more pair of parantheses in declaration to assert about
return value. This will complete the design as a communication to the
user who links the function (method) to her own code as well as will
generate a robust code.

For example, in C,

Current Declaration:
int *g (int i, int *j, int k);

Possible Extension 2:
int *g (
int i {
i > 0 && i < INT_MAX
},
int *j {
j != NULL
},
int k {
k != some_global
}
) (
j != NULL && __RETURN_VALUE__ != NULL
);

Advantages:
1. Clear communication to the person who links her code
2. Robust programming
3. Definitions (function bodies) become more readable
4. Assertions become more maintainable

Issues:
3.1 Can compare with constants and globals only. Those should be
visible in the .h file
3.2 As the standard does not (and probably will not) impose order of
evaluation of argument, we can not use one argument in assertion of
another argument. (We can not default to another argument in C++ for
the same reason, I guess.)
3.3 In a sense it violates WYSIWYG nature of C. No problem with C++
3.4 It may slow down execution. Compilers should provide a switch to
bypass assertions
3.5 Necessitates some error handler for assertion failure. (A good
code must already linking with some sort of <assert.h> or equivalent.)
3.6 Recursive call in an assertion (calling f in assertion of f's
argument) and similar stuff
 
Reply With Quote
 
 
 
 
EventHelix.com
Guest
Posts: n/a
 
      01-05-2004
I think you should consider Eiffel syntax.
Eiffel supports design by contract programming and has a suitable
syntax.

The following article should be a starting point:
http://www.eventhelix.com/RealtimeMa...y_contract.htm

Sandeep
--
http://www.EventHelix.com/EventStudio
EventStudio 2.0 - System Architecture Design CASE Tool
 
Reply With Quote
 
 
 
 
puppet_sock@hotmail.com
Guest
Posts: n/a
 
      01-05-2004
(Bhushit Joshipura) wrote in message news:<. com>...
[snip]
> The idea:
>
> 1. Extend the concept of declaration (prototype) to a step further -
> alongwith parameters, we specify assertions about them too. When the
> function gets called (method gets invoked) these assertions, if
> present, are [optionally] invoked before hitting the body of the
> function.
>
> For example, in C,
>
> Current declaration:
> int f ( int i, int *j, int k);
>
> Possible extension 1:
> int f (
> int i {
> i > 0 && i < INT_MAX
> },
> int *j {
> j != NULL
> },
> int k {
> k != some_global
> }
> );


Hum. While it might be possible to put this in, it could not
be checked at compile time, at least not in general. You can't
always pre-compute the call values of functions. You can't even
pre-compute whether a function will actually be called.
So, these checks might be created, but they could only actually
be tested against at run time. The same is true for checking
return values.

> Advantages:
> 1. Clear communication to the person who links her code


Well, maybe. It does not necessarily happen that it's any
clearer to the client coder. I've always found that a good
set of documentation is worth a lot.

What happens if the user tweaks the .h file to change the limit?
Or even removes the limit, expecting to be able to get a log
function to take negative values. Might be undefined behaviour.

> 2. Robust programming
> 3. Definitions (function bodies) become more readable
> 4. Assertions become more maintainable


Possibly. Though it seems like it's just moving testing from
inside the code to insde the function call. It may make it a
tad more visible, and make documentation slightly more
automatic.

> Issues:
> 3.1 Can compare with constants and globals only. Those should be
> visible in the .h file


What happens if one of those constants gets changed?

> 3.3 In a sense it violates WYSIWYG nature of C. No problem with C++


What is "WYSIWYG nature of C?" I've always found that C has a
"WYGIWYG nature." That is, "what you get is what you get."

> 3.5 Necessitates some error handler for assertion failure. (A good
> code must already linking with some sort of <assert.h> or equivalent.)


I should think it would throw an exception in C++.
Socks
 
Reply With Quote
 
Howard
Guest
Posts: n/a
 
      01-05-2004

"Bhushit Joshipura" <> wrote in message
news: om...
>
> Advantages:
> 1. Clear communication to the person who links her code


Clear? Looks like a nightmare to me. I'd have a hard time seeing quickly
what parameters a function needs. You can already put whatever assertion
you like in the body of the function. Why put them in the declaration? And
good documentation provides the "contract" just as well, and in plainer
language.

> 2. Robust programming


Meaning what? How are they more robust than using assertions in the
function body?

> 3. Definitions (function bodies) become more readable


Why? What's being removed from the function body? A few assertions at the
start (if you even use those in the first place)? I think they're much more
readable in the function body than mingled with the parameter list.

> 4. Assertions become more maintainable


Why is the header file more maintainable? I would argue the opposite.
Changes in the function body, when stored in an implementation file instead
of a header file, require far less compilation work than changes to a
header, which can force massive recompilations.

>
> Issues:
> 3.1 Can compare with constants and globals only. Those should be
> visible in the .h file
> 3.2 As the standard does not (and probably will not) impose order of
> evaluation of argument, we can not use one argument in assertion of
> another argument. (We can not default to another argument in C++ for
> the same reason, I guess.)
> 3.3 In a sense it violates WYSIWYG nature of C. No problem with C++


Not sure what you mean here. WYSIWYG usually refers to what you "see", as
in a graphical layout tool that produces the results exactly as you design
them (which, if you've ever used it, VC++ does NOT).

> 3.4 It may slow down execution. Compilers should provide a switch to
> bypass assertions


Definitely slows down execution. Assertions are used for debug builds, and
turned off for release builds. But you often want to write code that checks
value ranges, especially for parameters, which does NOT get removed for the
release build. Totally your decision which to use where, but I still think
both types belong in the function body, which is where the details of
implementation exist.

> 3.5 Necessitates some error handler for assertion failure. (A good
> code must already linking with some sort of <assert.h> or equivalent.)
> 3.6 Recursive call in an assertion (calling f in assertion of f's
> argument) and similar stuff


Recursive calls? Kind of violates you earlier principle that you can only
check against constants, doesn't it?

I sincerely doubt you'll see much support for this. It's kind of messy, and
doesn't really provide much we don't have already. Think of all the
existing compilers that would be unable to read it, too!

-Howard






 
Reply With Quote
 
jeffc
Guest
Posts: n/a
 
      01-05-2004

"Howard" <> wrote in message
news:btcjbt$...
>
> "Bhushit Joshipura" <> wrote in message
> news: om...
> >
> > Advantages:
> > 1. Clear communication to the person who links her code

>
> Clear? Looks like a nightmare to me. I'd have a hard time seeing quickly
> what parameters a function needs. You can already put whatever assertion
> you like in the body of the function. Why put them in the declaration?


Because client programmers often cannot see the function body. (This is not
an endorsement of the OP's method.)


 
Reply With Quote
 
Howard
Guest
Posts: n/a
 
      01-05-2004

"jeffc" <> wrote in message
news:...
>
> "Howard" <> wrote in message
> news:btcjbt$...
> >
> > "Bhushit Joshipura" <> wrote in message
> > news: om...
> > >
> > > Advantages:
> > > 1. Clear communication to the person who links her code

> >
> > Clear? Looks like a nightmare to me. I'd have a hard time seeing

quickly
> > what parameters a function needs. You can already put whatever

assertion
> > you like in the body of the function. Why put them in the declaration?

>
> Because client programmers often cannot see the function body. (This is

not
> an endorsement of the OP's method.)
>
>


If it's only for the client programmer, than it belongs in documentation,
not code, IMO. The function header defines the parameters for use by the
compiler, not by the programmer. Proper documentation is what is needed for
the client programmer to do his/her job correctly.

(Now, while understanding you're not advocating the OP's position...)

Aside from exposing details best left to either the implementation or to
documentation, it is incomplete. How do you specify, for example,
pre-condtions that do not meet his simple test examples, such as "you must
first have a valid FTP connection", or "if member A of the passed reference
parameter is non-zero, then the B member struct must be filled out with
appropriate values"? If you can't solve the whole problem, why make things
worsse just to slve a tiny part of it?

-Howard


 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      01-05-2004
Howard wrote:
>
> "Bhushit Joshipura" <> wrote in message
> news: om...
> >
> > Advantages:
> > 1. Clear communication to the person who links her code

>
> Clear? Looks like a nightmare to me. I'd have a hard time seeing quickly
> what parameters a function needs. You can already put whatever assertion
> you like in the body of the function. Why put them in the declaration? And
> good documentation provides the "contract" just as well, and in plainer
> language.


Compiler-digestible assertions could have utility beyond
just debugging. For example, if the compiler can be made to
understand that a function argument is not merely an `int' but
a non-negative `int', optimizations like replacing divisions
with shifts might be applicable. If the compiler can also be
told that the `int' is in the range [0..9], say, it could omit
some needless range-checking code in

switch (zero_through_nine) {
case 0: ... ; break;
case 1: ... ; break;
case 2: ... ; break;
case 3: ... ; break;
case 4: ... ; break;
case 5: ... ; break;
case 6: ... ; break;
case 7: ... ; break;
case 8: ... ; break;
case 9: ... ; break;
}

However, I'm not convinced that the proposed mechanism would
be expressive enough to enable optimizations that would repay
the added burdens. I'm sure I'd find myself wanting to say
that the function `int kbhit()' "almost always" returns zero,
for example.

--

 
Reply With Quote
 
Bhushit Joshipura
Guest
Posts: n/a
 
      01-05-2004
I think we should name this feature.
in C: assertive prototype
in C++: assertive declaration

> [snip]
> > The idea:

[snip]
> Hum. While it might be possible to put this in, it could not
> be checked at compile time, at least not in general. You can't
> always pre-compute the call values of functions. You can't even
> pre-compute whether a function will actually be called.
> So, these checks might be created, but they could only actually
> be tested against at run time. The same is true for checking
> return values.


You are correct. It *is* meant for runtime. It has to be. We are going
to assert against actual parameters.

> > Advantages:
> > 1. Clear communication to the person who links her code

>
> Well, maybe. It does not necessarily happen that it's any
> clearer to the client coder. I've always found that a good
> set of documentation is worth a lot.
>
> What happens if the user tweaks the .h file to change the limit?
> Or even removes the limit, expecting to be able to get a log
> function to take negative values. Might be undefined behaviour.


It would not change the behavior because the function / method was
compiled with original set of values. However, this may throw things
out of sync. Does not the same happen in case of header files now?

> > 2. Robust programming
> > 3. Definitions (function bodies) become more readable
> > 4. Assertions become more maintainable

>
> Possibly. Though it seems like it's just moving testing from
> inside the code to insde the function call. It may make it a
> tad more visible, and make documentation slightly more
> automatic.


.... and code slightly more robust. We are discussing this years after
a little step of introduction of prototypes to C was taken. That too
improved life a little. Tomorrow comes yet another idea in some brain
and we will have one more step towards better life.

> > Issues:
> > 3.1 Can compare with constants and globals only. Those should be
> > visible in the .h file

>
> What happens if one of those constants gets changed?


Constants won't change (or they would be variables!. Globals may
change.

The very fact that the assertive declaration uses a global, implies
that it must depend on temporal value of the global. So (barring race
conditions), anything referring to a global will (luckily) change
behavior with the value of that global.

> > 3.3 In a sense it violates WYSIWYG nature of C. No problem with C++

>
> What is "WYSIWYG nature of C?" I've always found that C has a
> "WYGIWYG nature." That is, "what you get is what you get."


You are correct again. C is highly (and perhaps uniquely) WYSIWYG.

Assertive prototypes sort of violate that nature because assertions
won't be "seen in .c file". Implementation will happen "out of the
body of function".

However, assertive prototypes will still be highly predictable because
they actually steal the code from function body and put before (or
after) the body.

> > 3.5 Necessitates some error handler for assertion failure. (A good
> > code must already linking with some sort of <assert.h> or equivalent.)

>
> I should think it would throw an exception in C++.
> Socks


-Bhushit
 
Reply With Quote
 
Douglas A. Gwyn
Guest
Posts: n/a
 
      01-06-2004
Howard wrote:
> You can already put whatever assertion
> you like in the body of the function.


Exactly.
And in fact, many functions have prerequisites for the data
structures with which they operate that would need much more
extensive validation than a simple range check.

The history of programming is full of examples of people
trying to automate correctness by linguistic constructs,
and Lo! they haven't succeeded. It's the wrong approach.

 
Reply With Quote
 
Hallvard B Furuseth
Guest
Posts: n/a
 
      01-06-2004
Eric Sosman wrote:

> Compiler-digestible assertions could have utility beyond
> just debugging. For example, if the compiler can be made to
> understand that a function argument is not merely an `int' but
> a non-negative `int', optimizations like replacing divisions
> with shifts might be applicable.


True. However, that belongs in the function body, not in the
declaration. Then the assertions can also be used about other
variables, e.g. to assert loop invariants.

Assertions about the return value from the function belong in
the declaration, however.

> However, I'm not convinced that the proposed mechanism would
> be expressive enough to enable optimizations that would repay
> the added burdens. I'm sure I'd find myself wanting to say
> that the function `int kbhit()' "almost always" returns zero,
> for example.


One could support both __Expect(return == 0) which describes the
usual return value, and __Assert(return >= 0) which describes all
return values.

--
Hallvard
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
What's the difference between function declaration and function prototype? Hill Pang C Programming 8 09-05-2012 08:21 AM
Class prototype vs C function prototype June Lee C++ 2 04-13-2008 08:17 PM
function prototype declaration Sheldon C Programming 8 02-28-2008 05:06 PM
function prototype vs function declaration Ravishankar S C Programming 44 12-23-2007 11:40 AM
Variable declaration or function prototype Andrew Ward C++ 6 09-11-2003 07:41 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57