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
14 1731
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
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.
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). da********@warp mail.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." da********@warp mail.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 This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
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 concerning the issue
of errors/exceptions raised during assertion evaluation. The
questionnaire is available here:
https://www.dsrg.org/ASN_Survey/wnd.html
Thank-you in advance,
P.Chalin
|
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 of the
assert macro - it provides the desired functionality but only if
NDEBUG is not defined. So, I could write smth like this:
#if defined NDEBUG
#undef NDEBUG
#include <cassert>
#define NDEBUG
|
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
assertion... and on average, every 5th line is an assertion.
My question:
Do any of you include that many assertions? I agree in principle that we
should code defensively, but his recommendation just seems to go "overboard"
and would result in a lot of...
|
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 VB.NET have a feature where
you can turn off assertions on production code?
--
http://www.douglass.com
|
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.
| |
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 been
explained to my satisfaction.
I recently read this explanation. "There is an effective litmus test
to differentiate the cases in which you need to use assert and when
you need to use genuine error checking: you use error checking for...
|
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, I'd always understood that assertions were only
fired in debug builds and would compile down to NOPs in release builds
(for good reasons)
Now it looks as though I have to be careful to code assertions
conditionally?
|
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 assertions generally?
On a more general note, how does one reconcile a changing data set with
testing driven development?
|
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look !
Part I. Meaning of...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed.
This is as boiled down as I can make it.
Here is my compilation command:
g++-12 -std=c++20 -Wnarrowing bit_field.cpp
Here is the code in...
|
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
| |
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
|
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own....
Now, this would greatly impact the work of software developers. The idea...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules.
He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms.
Adolph will...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one.
At the time of converting from word file to html my equations which are in the word document file was convert into image.
Globals.ThisAddIn.Application.ActiveDocument.Select();...
|
by: TSSRALBI |
last post by:
Hello
I'm a network technician in training and I need your help.
I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs.
The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols.
I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
|
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
| |