473,405 Members | 2,334 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,405 software developers and data experts.

Use of Assertions

Hi,
is it a nice idea to do assetion checks for method arguments ? I
am currently redesigning a piece of code. Now the problem is that there
are some assumptions for the method arguments that the code makes. It
is not checking the validity of the arguments everywhere because that
would lead to performance penalty. So I am think that at least
assertions will be able check the arguments at least for debug version
to verify the design. But now it means that I put the assertions
everywhere in the code, something like below:

Code with out checks

func1(Ptr1 * ptr1, Ptr2 * ptr2)
{
ptr2->do something...
ptr1->call some method(ptr2);
}

Code with assertions
func1(Ptr1 * ptr1, Ptr2 * ptr2)
{
assert( ptr1!= NULL && ptr2 != NULL); // And do this for all
functions with arguments everywhere
ptr2->do something...
ptr1->call some method(ptr2);
}

so my questions really is : Is it a good idea to put the assertions for
the function arguments like shown above? Why or why not?

Thanks,
Divick

Feb 15 '06 #1
14 1680
Divick wrote:
Hi,
is it a nice idea to do assetion checks for method arguments ? I
YES.

.... }

Code with assertions
func1(Ptr1 * ptr1, Ptr2 * ptr2)
{
assert( ptr1!= NULL && ptr2 != NULL); // And do this for all
assert( ptr1 )
assert( ptr2 )

Validate *each* argument rather than have one long expression.

NULL *is* 0 is C++. I don't use NULL any more (personal preference).

functions with arguments everywhere
ptr2->do something...
ptr1->call some method(ptr2);
}

so my questions really is : Is it a good idea to put the assertions for
the function arguments like shown above? Why or why not?


It's a good idea because:

a) It documents your assumptions and enforces them (at least in debug).
b) It catches errors early (which is always desirable).
Feb 15 '06 #2
* Divick:
Hi,
is it a nice idea to do assetion checks for method arguments ? I
am currently redesigning a piece of code. Now the problem is that there
are some assumptions for the method arguments that the code makes. It
is not checking the validity of the arguments everywhere because that
would lead to performance penalty. So I am think that at least
assertions will be able check the arguments at least for debug version
to verify the design. But now it means that I put the assertions
everywhere in the code, something like below:

Code with out checks

func1(Ptr1 * ptr1, Ptr2 * ptr2)
{
ptr2->do something...
ptr1->call some method(ptr2);
}

Code with assertions
func1(Ptr1 * ptr1, Ptr2 * ptr2)
{
assert( ptr1!= NULL && ptr2 != NULL); // And do this for all
functions with arguments everywhere
ptr2->do something...
ptr1->call some method(ptr2);
}

so my questions really is : Is it a good idea to put the assertions for
the function arguments like shown above?
No.

Why or why not?


Use reference arguments where you don't intend to support NULL-values.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Feb 15 '06 #3
Divick wrote:
Hi,
is it a nice idea to do assetion checks for method arguments ? I
am currently redesigning a piece of code. Now the problem is that there
are some assumptions for the method arguments that the code makes. It
is not checking the validity of the arguments everywhere because that
would lead to performance penalty.


1st priority: Correctness.
2nd priority: Correctness!

Much lower priority: Performance.

Always validate the arguments, if there IS a performance penalty convert
the ones that matter to assertions.

If the input comes from the user, or a file or something, then
assertions are not really a suitable option. Validate those things ASAP
to contain the problem.

Ben Pope
--
I'm not just a number. To many, I'm known as a string...
Feb 15 '06 #4
>>Use reference arguments where you don't intend to support NULL-values.
Could you please give an example?

Seems like people have different opinions about this. Confused...:(

Divick

Feb 15 '06 #5
Hi Divick
Use reference arguments where you don't intend to support NULL-values.

Could you please give an example?

Seems like people have different opinions about this. Confused...:(


I do not think many people have different opinions on this. :-)

Those who said that you should use assertions to make sure
your pointer parameters are not 0 were assuming you had a
reason for using pointers in the first place. What Alf said was
that you the question of whether to use assertions for this should
not be an issue if you do not need pointers here but can use
references.

In other words....
1. use assertions where needed.
2. use references instead of pointers wherever possible.

Just my two cents worth... and I hope it helps...

Best regards,
Jurko Gospodnetic
Feb 15 '06 #6
>>Those who said that you should use assertions to make sure
your pointer parameters are not 0 were assuming you had a
reason for using pointers in the first place. What Alf said was
that you the question of whether to use assertions for this should
not be an issue if you do not need pointers here but can use
references.

Ok, that helps. Now I understand what Alf was trying to say.

Thanks a lot,
Divick

Feb 15 '06 #7
Gianni Mariani wrote:

NULL *is* 0 is C++. I don't use NULL any more (personal preference).


Yes, but what about problems like that which was discussed
recently:

http://groups.google.com/group/comp....93d210e3c2b5cb

- J.
Feb 16 '06 #8
Divick wrote:
Hi,
is it a nice idea to do assetion checks for method arguments ?


Yes! Better safe than sorry.

If you are worried about performance (better support this
with an actual time-test, rather than thinking "this could
be too slow"), you might have two styles of asserts, like

Assert(...)
and
CostlyAssert(...)

that would be turned on/off independently with preprocessor
stuff like

#define WANT_ASSERTS
#define WANT_COSTLYASSERTS

Then you could leave Asserts on for both debug and release
versions and turn CostlyAsserts only for debugging.

HTH,
- J.
Feb 16 '06 #9
Jacek Dziedzic wrote:
Gianni Mariani wrote:

NULL *is* 0 is C++. I don't use NULL any more (personal preference).


Yes, but what about problems like that which was discussed
recently:

http://groups.google.com/group/comp....93d210e3c2b5cb


That's a gem.

Yes, function overloading with templates and the special meaning of
literal 0 gets "overloaded".

It's too late now, but I think the language rules around the 0 literal
and null pointers to now be a bad idea. The NULL macro provides no help
here from a readability perspective, so I think that's a bad idea as
well (IMHO).
Feb 16 '06 #10

Divick wrote:
Hi,
is it a nice idea to do assetion checks for method arguments ? I
am currently redesigning a piece of code. Now the problem is that there
are some assumptions for the method arguments that the code makes. It
is not checking the validity of the arguments everywhere because that
would lead to performance penalty. So I am think that at least
assertions will be able check the arguments at least for debug version
to verify the design. But now it means that I put the assertions
everywhere in the code, something like below:

Code with out checks

func1(Ptr1 * ptr1, Ptr2 * ptr2)
{
ptr2->do something...
ptr1->call some method(ptr2);
}

Code with assertions
func1(Ptr1 * ptr1, Ptr2 * ptr2)
{
assert( ptr1!= NULL && ptr2 != NULL); // And do this for all
functions with arguments everywhere
ptr2->do something...
ptr1->call some method(ptr2);
}

so my questions really is : Is it a good idea to put the assertions for
the function arguments like shown above? Why or why not?


One way to look at a function call is as a contract between two
parties: the caller promises that certain things will be true before
making the function call (these are known as the preconditions), while
the callee (the function being called) makes certain promises about
what will be true after the function call completes (these known as the
postconditions). Assertions are used during development to check that
both sides are holding up their ends of bargain. And when errors are
detected, it is clear whether the error is located in the client's code
or in the function being called.

In this case, an assert that checks for NULL pointer parameters would
mean that the client has promised never to pass a NULL pointer as a
parameter. So a precondition of calling this routine is that all
pointer parameters be non-NULL. But much of the reason for passing an
argument by pointer is to allow certain values to be missing (or
optional). So if the value must be present it makes more sense to
declare the function with a reference parameter, since doing so better
communicates to the client the necessary preconditions. And if a
reference is for some reason impractical, at least the function
declaration could use a typedef, for instance an IntRef instead of an
int * to help convey to the caller that although the parameter type is
in fact a pointer, it is expected to refer to an extant instance of the
pointer type and not be NULL.

A great many bugs in software can be traced to vague notions about a
function's preconditions and postconditions. Clearly defining both, and
using assertions to verify compliance during development are two of the
most effective ways to assure quality in the finished application.

Greg

Feb 16 '06 #11

Divick wrote:
Hi,
is it a nice idea to do assetion checks for method arguments ? I
am currently redesigning a piece of code. Now the problem is that there
are some assumptions for the method arguments that the code makes. It
is not checking the validity of the arguments everywhere because that
would lead to performance penalty. So I am think that at least
assertions will be able check the arguments at least for debug version
to verify the design. But now it means that I put the assertions
everywhere in the code, something like below:

Code with out checks

func1(Ptr1 * ptr1, Ptr2 * ptr2)
{
ptr2->do something...
ptr1->call some method(ptr2);
}

Code with assertions
func1(Ptr1 * ptr1, Ptr2 * ptr2)
{
assert( ptr1!= NULL && ptr2 != NULL); // And do this for all
functions with arguments everywhere
ptr2->do something...
ptr1->call some method(ptr2);
}

so my questions really is : Is it a good idea to put the assertions for
the function arguments like shown above? Why or why not?


In this particular case, it's not a good idea to check parameters. All
you need to do is specify in the contract of your interface that the
behavior is undefined unless the parameters are valid. In most cases,
you should assume that the behavior is undefined if you pass a null
pointer where a pointer argument is expected. Thus, you typically
specify when you *can* pass a null pointer, rather than when you can't.

The place you do want to use assertions is to verify invariants. For
example, if you have a class that represents a positive integer, you
want to assert that the representation is a positive integer. Usually
you can do this in the destructor. This lets you use the class without
much performance penalty, but still catch "impossible" errors.

Feb 16 '06 #12

Greg wrote:
But much of the reason for passing an
argument by pointer is to allow certain values to be missing (or
optional). So if the value must be present it makes more sense to
declare the function with a reference parameter, since doing so better
communicates to the client the necessary preconditions.
I have to disagree with this. Using a (modifiable) reference argument
to enforce the precondition that a valid (i.e., "non-null") argument
must be supplied obfuscates the possibility that the value will be
modified. OTOH, any time a non-const pointer is used as an argument,
the caller must always assume that the value will be modified. This is
a long-standing opinion.
And if a
reference is for some reason impractical, at least the function
declaration could use a typedef, for instance an IntRef instead of an
int * to help convey to the caller that although the parameter type is
in fact a pointer, it is expected to refer to an extant instance of the
pointer type and not be NULL.
This kind of typedef is of no use to anyone. In no way does it imply
that the parameter cannot by NULL. In fact, it doesn't even indicate
that the parameter is a pointer. It just obfuscates the interface.
A great many bugs in software can be traced to vague notions about a
function's preconditions and postconditions. Clearly defining both, and
using assertions to verify compliance during development are two of the
most effective ways to assure quality in the finished application.


I do agree with this. All you need is a clearly defined contract, and
possibly some assertions (to verify invariants).

Feb 16 '06 #13

da********@warpmail.net wrote:
Greg wrote:
But much of the reason for passing an
argument by pointer is to allow certain values to be missing (or
optional). So if the value must be present it makes more sense to
declare the function with a reference parameter, since doing so better
communicates to the client the necessary preconditions.


I have to disagree with this. Using a (modifiable) reference argument
to enforce the precondition that a valid (i.e., "non-null") argument
must be supplied obfuscates the possibility that the value will be
modified. OTOH, any time a non-const pointer is used as an argument,
the caller must always assume that the value will be modified. This is
a long-standing opinion.


There's no reason why a reference has to be modifiable. Pointer or
reference, both cases you use const to mean, "I'm not going to modify
this."

Feb 16 '06 #14

da********@warpmail.net wrote:
Greg wrote:
But much of the reason for passing an
argument by pointer is to allow certain values to be missing (or
optional). So if the value must be present it makes more sense to
declare the function with a reference parameter, since doing so better
communicates to the client the necessary preconditions.


I have to disagree with this. Using a (modifiable) reference argument
to enforce the precondition that a valid (i.e., "non-null") argument
must be supplied obfuscates the possibility that the value will be
modified. OTOH, any time a non-const pointer is used as an argument,
the caller must always assume that the value will be modified. This is
a long-standing opinion.


Why would the client be calling the function unless the client knows
the reason for calling the routine and what the routine does? If the
client knows what and why it it is calling a function, than the fact
that some parameters may be references whose value may change is all
well and good, since that type of change is precisely why the function
is being called.

The idea that it must be clear whether a parameter in a function call
is a pointer or a reference or a value is a crutch left over from C.
Such an emphasis simply means that the program isn't really sure what
it is doing and has to limit the bad consequences that flow from that
fact.
And if a
reference is for some reason impractical, at least the function
declaration could use a typedef, for instance an IntRef instead of an
int * to help convey to the caller that although the parameter type is
in fact a pointer, it is expected to refer to an extant instance of the
pointer type and not be NULL.


This kind of typedef is of no use to anyone. In no way does it imply
that the parameter cannot by NULL. In fact, it doesn't even indicate
that the parameter is a pointer. It just obfuscates the interface.


This technique is commonly used in many well known and widely used
APIs. Such a typedef is usually called a "Handle", that is, a reference
to some (often opaque) data structure that the client passes to various
routines in an API. A client needs a valid Handle in order to call
these routines. It cannot pass NULL even though the Handle's type is in
fact a pointer.

It is far more important to focus on the meaning of the parameters to a
function call rather than their form. Fixating on pointers vs.
references vs. value is the wrong emphasis since it tries to limit what
can happen in the function call. Instead the proper focus should be on
what the client can expect to be true after the function call
completes.

Greg

Feb 17 '06 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: P. Chalin | last post by:
If you make use of assertions (e.g. assert statements) in your code, I would like to invite you to participate in a 15 min survey on program assertions. In this survey we seek your opinion...
14
by: Angel Tsankov | last post by:
I need to make verifications in release builds. If a verification fails, an error message should be displayed and the program should be aborted. I need this solution to be portable. Then I thought...
8
by: Jefffff | last post by:
Regarding the use of assertions: According to Juval Lowy's excellent coding standards document (PDF download available at www.idesign.net), every assumption in your code should have an...
4
by: douglass_davis | last post by:
Say I would like to use assertions to make sure correct inputs are given to a procedure. But, I want to do this in testing only, not in production. I saw Debug.Assert, which is nice, but does...
10
by: Matthew Wilson | last post by:
Lately, I've been writing functions like this: def f(a, b): assert a in assert b in The point is that I'm checking the type and the values of the parameters.
58
by: jeffc226 | last post by:
This might be less of a design issue than a C++ language issue per se, but I have a problem with assertions. I mean, they work, of course. But there's something I'm uncomfortable with that's never...
0
by: Duncan Smith | last post by:
Last week, I got reports back of errors in a patch I let someone try out (release dll, but not from the build machine). Turns out it was some Debug::Assert statements firing. In umanaged code,...
3
by: Hugh Oxford | last post by:
I am told that I should use assertions in my testing. The problem is, because I test using a cut of live data, the data always changes. Has anyone come up against this or have they abandoned...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.