473,587 Members | 2,230 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

use assert and defensive together

hello,
please see following two code snatches:
1.
int foo (const char* some)
{
assert(some);
if (!some)
{
return -1; //-1 indicates error
}
...
}

2.
int foo (const char* some)
{
if (!some)
{
assert(some);
return -1; // -1 indicates error
}
...
}

what’s the preference of you or none of them? why? I prefer the second
but I cannot persuade my friends.

regards,
Sep 23 '08 #1
32 2053
On Sep 22, 9:25*pm, bingfeng <bf****@gmail.c omwrote:
hello,
please see following two code snatches:
1.
int foo (const char* some)
{
* * assert(some);
* * if (!some)
* * {
* * * * return -1; //-1 indicates error
* * }
* * ...

}

2.
int foo (const char* some)
{
* * if (!some)
* * {
* * * * assert(some);
* * * * return -1; // -1 indicates error
* * }
* * ...

}

what’s the preference of you or none of them? why? I prefer the second
but I cannot persuade my friends.
They both will do the same thing regardless of whether 'some'
evaluates to true or false, so it's only a matter of style. I'd say I
prefer the first; the second seems like an abuse of the assert()
macro, since it will always terminate the program (you already know it
will!).

Sebastian

Sep 23 '08 #2
On Mon, 22 Sep 2008 19:25:31 -0700 (PDT), bingfeng <bf****@gmail.c om>
wrote:
>hello,
please see following two code snatches:
1.
int foo (const char* some)
{
assert(some);
if (!some)
Can this expression ever evaluate to true?
{
return -1; //-1 indicates error
}
...
}

2.
int foo (const char* some)
{
if (!some)
{
assert(some);
return -1; // -1 indicates error
Can this statement ever be reached?
}
...
}

what’s the preference of you or none of them? why? I prefer the second
but I cannot persuade my friends.

regards,
--
Remove del for email
Sep 23 '08 #3
bingfeng <bfz...@gmail.c omwrote:
hello,
please see following two code snatches:
1.
int foo (const char* some)
{
* * assert(some);
* * if (!some)
* * {
* * * * return -1; //-1 indicates error
* * }
* * ...
}

2.
int foo (const char* some)
{
* * if (!some)
* * {
* * * * assert(some);
* * * * return -1; // -1 indicates error
* * }
* * ...
}

what’s the preference of you or none of them? why?
I generally prefer to test function preconditions
immediately on entry.

I also believe that asserts should be left in production
code. Otherwise your development environment is not
matching your production environment and you introduce
an element of risk in testing.

If this is 'critical' code that cannot aford to abort,
then there's even more reason not to introduce
differences between production and development
environments. [In other words, dump the asserts altogether.]
I prefer the second but I cannot persuade my friends.
You haven't said why you prefer it?

I don't think I would like having to sift through the
whole body of a function to make sure I've found all
the precondition asserts (should they change.) That
said, asserts are powerful things. If you change one,
you should review them all.

--
Peter
Sep 23 '08 #4
Barry Schwarz <schwa...@dqel. comwrote:
bingfeng <bfz...@gmail.c omwrote:
hello,
please see following two code snatches:
1.
int foo (const char* some)
{
* *assert(some);
* *if (!some)

Can this expression ever evaluate to true?
Yes, when NDEBUG is defined and a null pointer is passed to foo.
* *{
* * * *return -1; //-1 indicates error
* *}
* *...
}

2.
int foo (const char* some)
{
* *if (!some)
* *{
* * * *assert(some);
* * * *return -1; // -1 indicates error

Can this statement ever be reached?
Ditto.
* *}
* *...
}
--
Peter
Sep 23 '08 #5
On Sep 23, 10:52*am, s0s...@gmail.co m wrote:
On Sep 22, 9:25*pm, bingfeng <bfz...@gmail.c omwrote:
hello,
please see following two code snatches:
1.
int foo (const char* some)
{
* * assert(some);
* * if (!some)
* * {
* * * * return -1; //-1 indicates error
* * }
* * ...
}
2.
int foo (const char* some)
{
* * if (!some)
* * {
* * * * assert(some);
* * * * return -1; // -1 indicates error
* * }
* * ...
}
what’s the preference of you or none of them? why? I prefer the second
but I cannot persuade my friends.

They both will do the same thing regardless of whether 'some'
evaluates to true or false, so it's only a matter of style. I'd say I
prefer the first; the second seems like an abuse of the assert()
macro, since it will always terminate the program (you already know it
will!).
Indeed, I think assert and defensive style is conflict here. General,
by using assert, you tell reader that the condition will not occur in
any case, so if sentence is not necessary. Obey the contract between
this function and client codes is the responsibility of
client. This requires you can control the client codes or the owner of
client codes has a strict contract with you. Of course, if the input
is from untrusted source, you'll definitely check every arguments you
get and make sure it's correct. assert is not for this scenario.

So I never use assert and defensive checking together. I prefer second
since I was forced select one from them. Apart from documenting codes
and asserting contact, assert can raise explicit break under debug
mode if possible, which give a very good change to check at once. This
maybe acceptable under some conditions of early stage of development.
Sebastian
bingfeng
Sep 23 '08 #6
On 23 Sep, 03:25, bingfeng <bfz...@gmail.c omwrote:
hello,
please see following two code snatches:
1.
int foo (const char* some)
{
* * assert(some);
* * if (!some)
* * {
* * * * return -1; //-1 indicates error
* * }
* * ...

}

2.
int foo (const char* some)
{
* * if (!some)
* * {
* * * * assert(some);
* * * * return -1; // -1 indicates error
* * }
* * ...

}

what’s the preference of you or none of them? why? I prefer the second
but I cannot persuade my friends.
Both of those code snippets are atrocities. In the first, the
assertion is a statement of expectation on the part of
the function developer. In particular, "assert( some )",
which should be re-written as "assert( some != NULL )",
is a proclamation that the function expects the caller
not to pass in NULL, and if the caller does then anything
may happen. In particular, the function will not return
a useful error condition and may invoke undefined
behavior, etc. By then checking for NULL, the developer
is essentially wasting runtime doing things that (s)he
promised would not be done. Either check for a condition,
or make the caller do it by making an assertion. Do not
do both.

The 2nd case is much worse, though. It is the developer
saying, "At this point in the code, I believe it is
logically impossible that the variable some has
a NULL value." Since it is inside a condition which
can only be reached when some is NULL, the developer
is clearly using a very powerful hallucinogenic.

Sep 23 '08 #7
William Pursell <bi**********@g mail.comwrites:
On 23 Sep, 03:25, bingfeng <bfz...@gmail.c omwrote:
>hello,
please see following two code snatches:
1.
int foo (const char* some)
{
Â* Â* assert(some);
Â* Â* if (!some)
Â* Â* {
Â* Â* Â* Â* return -1; //-1 indicates error
Â* Â* }
Â* Â* ...

}

2.
int foo (const char* some)
{
Â* Â* if (!some)
Â* Â* {
Â* Â* Â* Â* assert(some);
Â* Â* Â* Â* return -1; // -1 indicates error
Â* Â* }
Â* Â* ...

}

what’s the preference of you or none of them? why? I prefer the second
but I cannot persuade my friends.

Both of those code snippets are atrocities. In the first, the
assertion is a statement of expectation on the part of
the function developer. In particular, "assert( some )",
which should be re-written as "assert( some != NULL )",
is a proclamation that the function expects the caller
not to pass in NULL, and if the caller does then anything
may happen. In particular, the function will not return
a useful error condition and may invoke undefined
behavior, etc. By then checking for NULL, the developer
is essentially wasting runtime doing things that (s)he
promised would not be done. Either check for a condition,
or make the caller do it by making an assertion. Do not
do both.

The 2nd case is much worse, though. It is the developer
saying, "At this point in the code, I believe it is
logically impossible that the variable some has
a NULL value." Since it is inside a condition which
can only be reached when some is NULL, the developer
is clearly using a very powerful hallucinogenic.
Interesting as I had only quickly glanced at this before.

I have found in the past that sprinkling "asserts" around code tends to
promote an ill founded sense of "good practice" and smug satisfaction in
"safe code".

Never having been a fan of asserts I find this thread a good example of
this. The assert usage was not questioned and is only assumed "to be
good".
Sep 23 '08 #8
On Sep 23, 11:50*am, William Pursell <bill.purs...@g mail.comwrote:
On 23 Sep, 03:25, bingfeng <bfz...@gmail.c omwrote:
hello,
please see following two code snatches:
1.
int foo (const char* some)
{
* * assert(some);
* * if (!some)
* * {
* * * * return -1; //-1 indicates error
* * }
* * ...
}
2.
int foo (const char* some)
{
* * if (!some)
* * {
* * * * assert(some);
* * * * return -1; // -1 indicates error
* * }
* * ...
}
what’s the preference of you or none of them? why? I prefer the second
but I cannot persuade my friends.

Both of those code snippets are atrocities. In the first, the
assertion is a statement of expectation on the part of
the function developer. *In particular, "assert( some )",
which should be re-written as "assert( some != NULL )",
is a proclamation that the function expects the caller
not to pass in NULL, and if the caller does then anything
may happen. *In particular, the function will not return
a useful error condition and may invoke undefined
behavior, etc. *By then checking for NULL, the developer
is essentially wasting runtime doing things that (s)he
promised would not be done. *Either check for a condition,
or make the caller do it by making an assertion. *Do not
do both.
yes, agree. should be assert(!some) both, typo.
The 2nd case is much worse, though. *It is the developer
saying, "At this point in the code, I believe it is
logically impossible that the variable some has
a NULL value." *Since it is inside a condition which
can only be reached when some is NULL, the developer
is clearly using a very powerful hallucinogenic.
Not only do we use assert to document impossibility and contract,
assert has another practical function to catch unexpected parameter
immediately. Say two groups of a team develop different components of
a big application and the both two components have interfaces to
other. They must do defensive check before use any value another
module pass in since they don't want to crash. However, an invalid
value means other module maybe in a incorrect condition, if they can
catch such potential bug during debug process, it's very helpful.
assert will give an explicit break and it's better than log and check
the message later. Maybe rewrite the second assert(some) as assert(!
some && "Invalid parameter from caller X") is more explicit. It's
*acceptable* in practice, IMO.
Sep 23 '08 #9
William Pursell <bill.purs...@g mail.comwrote:
bingfeng <bfz...@gmail.c omwrote:
hello,
please see following two code snatches:
1.
int foo (const char* some)
{
* * assert(some);
* * if (!some)
* * {
* * * * return -1; //-1 indicates error
* * }
* * ...
}

2.
int foo (const char* some)
{
* * if (!some)
* * {
* * * * assert(some);
* * * * return -1; // -1 indicates error
* * }
* * ...
}
what’s the preference of you or none of them? why?
I prefer the second but I cannot persuade my friends.

Both of those code snippets are atrocities. *In the
first, the assertion is a statement of expectation on
the part of the function developer.
Any assert in a function body is such a statement.
>*In particular, "assert( some )", which should be re-
written as "assert( some != NULL )",
For C90 conformance certainly.
is a proclamation that the function expects the caller
not to pass in NULL,
No, it's merely a proclamation that if NDEBUG is not
defined, the program will abort if given a null pointer.
Assert is a debugging tool. It's the requirements
specification that contains the proclamations.
and if the caller does then anything may happen.
Developers often write additional development code to
facilitate finding bugs. [E.g. checking linked lists
for loops, etc...] Such code needn't always see
the light of production.
>*In particular, the function will not return
a useful error condition and may invoke undefined
behavior, etc.
It seems clear the two samples wish to avoid UB
whether the assert passes or fails.
>*By then checking for NULL, the developer
is essentially wasting runtime doing things that (s)he
promised would not be done.
Developers do waste a lot of runtime. ;)
>*Either check for a condition,
or make the caller do it by making an assertion.
Assertions do not force the caller to check the condition.
>*Do not do both.
I agree, but not for the reasons you state.
The 2nd case is much worse, though.*It is the developer
saying, "At this point in the code, I believe it is
logically impossible that the variable some has
a NULL value."
Again, it's merely a statement that if NDEBUG is not
defined, the program will abort if given a null pointer.
This may be deemed acceptable in a development environment,
but not in production.
>*Since it is inside a condition which
can only be reached when some is NULL, the developer
is clearly using a very powerful hallucinogenic.
No, IMO they've simply made a poor design decision that
introduces unnecessary risks.

--
Peter
Sep 23 '08 #10

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

Similar topics

28
3567
by: Fábio Mendes | last post by:
I'm sorry if it's an replicate. Either my e-mail program is messing with things or the python-list sent my msg to /dev/null. I couldn't find anything related in previous PEP's, so here it goes a very early draft for a new "assert" syntax: This was inspired in Ruby's assert syntax. I'm not familiar with Ruby at all, so the chances are that...
2
1464
by: John Black | last post by:
Hi, I am using assert() to hide some debug dump out like this, int dump(){ ... some printf... return 0; } then in my main code, I do this, assert(dump() == 0);
4
1824
by: August1 | last post by:
i'm having difficulties with the execution of a program, i believe due to something i am missing in the copy constructor implementation. When i create one object of the class and run the program with that object alone, there are no problems. however, when subsequently using the copy constructor for a second object and/or a third object created...
3
7724
by: Tony Johansson | last post by:
Hello Experts! I'm reading a book called programming with design pattern revealed by Tomasz Muldner and here I read something that I don' work. The text in the book says "To offer the programmer the choice of toggling between using and not using asser(), this function is used together with a macro called NDEBUG; when this macro is...
27
3820
by: Daniel Vallstrom | last post by:
I'm having problems with inconsistent floating point behavior resulting in e.g. assert( x > 0.0 && putchar('\n') && x == 0.0 ); holding. (Actually, my problem is the dual one where I get failed assertions for assertions that at first thought ought to hold, but that's not important.) At the end is a full program containing the above...
6
5041
by: Martin Ortiz | last post by:
Which is best approach? Should Try + Catch be used to only deal with "catastrophic" events (like divide by zero, non-existant file, etc...etc...) Or should Try + Catch be used IN PLACE of regular defensive programming? (ie if file exists do this, if not do something else) Or should Try + Catch be used TO SUPPLAMENT regular defensive...
0
8205
Oralloy
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. ...
0
8339
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
0
8220
tracyyun
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...
0
6619
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
0
3840
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...
0
3872
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2347
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
1
1452
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
1185
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

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.