Style Question - Checking for Poor Parameters

K

Kelsey Bjarnason

Not necessarily. Dereferecing NULL is going to fault on the spot.

Define "fault". If you mean "cause a segfault and the app will instantly
stop executing", I point you to, among others, DOS - in which you can
often happily dereference NULL without the application so much as
hiccupping.
 
X

xarax

Kelsey Bjarnason said:
Define "fault". If you mean "cause a segfault and the app will instantly
stop executing", I point you to, among others, DOS - in which you can
often happily dereference NULL without the application so much as
hiccupping.

It depends on the target platform and how the compiler implements
NULL internally. In the source code, NULL is zero. The compiler is
allowed to use any internal bit representation it wants for NULL
that it (the compiler) won't confuse with a valid pointer. Many
compilers simply use binary zero, which is fine with me, but for
portability I must remember that an internal NULL is not
necessarily zero.

Location zero may be accessible, depending on the target platform,
so the programmer should not rely on the machine to detect
dereferencing a NULL pointer.
 
J

James Dow Allen

xarax said:
It depends on the target platform and how the compiler implements

FWIW, Unix on some (DEC?) machines, IIRC, stored 0 at location 0.
Thus, the code
if (p == NULL || *p == 0)
return FAILURE;
could be "optimized" to just
if (*p == 0)
return FAILURE;

(In a vaguely similar vein, Data General machines had special addresses
where *p automatically became (*p)++ or (*p)--, and special pointers
where *p automatically became **p.)

Don't blame any of this on me, please; I'm just reporting
historical trivia.

James
 
D

Dan Pop

In said:
It depends on the target platform and how the compiler implements
NULL internally. In the source code, NULL is zero.

Nope, it's a four letter identifier. And there is no way to guess into
what the preprocessor will expand it.

Dan
 
A

Alan Balmer

Define "fault". If you mean "cause a segfault and the app will instantly
stop executing", I point you to, among others, DOS - in which you can
often happily dereference NULL without the application so much as
hiccupping.
In fact, I've used implementations which filled the area around *NULL
with special values, then reported a "NULL pointer error" if one of
those locations had changed at program exit.
 
G

goose

Erik de Castro Lopo said:
Michael B Allen wrote:

You are doing the right thing.

No checking is bad because the program will continue running
with bad state and crash somewhere else. The later crash may
or may not have any relation to where the bug is. If it is
unrelated it will be very difficult to figure out where the
real bug is.

In addition, if your library is going to be used by other
people and it crashes in your code, you will be blamed for
the crash even though the other person passed in bad data.

I think a little differently here.
Checking for errors = Good Thing.
Checking for bad args = It Depends.

Your function takes a pointer argument, right ? if the caller
passes a bad argument, how does it help to check the argument
for NULL ? out of the millions of different bad values that
the argument could possibly hold, you only check for one.

more to the point, the single check you make is for a value
(if the argument was not static at callers end) that will
possibly only result if the caller *explicitly* sets
it to that value.

If your library is going to be used by other people, then
make sure you document the behaviour of the functions when
the arguments are bad. then their code must play properly
with your code, e.g.

/* my header file for libfoo */
/* foo_1 results in UB if arg1 is an invalid
pointer, or if arg1 cannot be dereferenced.
*/
int foo_1 (char *arg1);

/* foo_2 will return the number of arguments
processed *IF* the argument list consists
entirely of valid pointers *AND* is terminated
by a NULL pointer *AND* has at least one
(possibly NULL) argument.
*/
int foo_1 (char *first_arg, ...);

you cannot stop the users of your library crashing
their program. If they cannot understand that
an argument should not be NULL, and pass it anyway,
its still all going to end in tears for them when
they (sooner or later) violate some other library.
Asserts are bad because program just prints an error message
and exits the program. This prevents the calling code from
attempting some sort of corrective action.

I never use asserts of any sort, although I am quite
fond of writing a DIAGNOSTIC() macro whenever I start
work on a new architecture.

hth
goose,
some people have it coming to them, I'm only
a delivery mechanism :).
 
D

Dan Pop

In said:
I think a little differently here.
Checking for errors = Good Thing.
Checking for bad args = It Depends.

Indeed. Checking for bad args makes sense only if it can be done in
a thorough manner and if the function specification promises such checks.
Your function takes a pointer argument, right ? if the caller
passes a bad argument, how does it help to check the argument
for NULL ? out of the millions of different bad values that
the argument could possibly hold, you only check for one.

Furthermore, these checks are not free. Why penalise the performance
of the correct programs, that never pass bad arguments, for the sake of
the broken programs, that do? It is the caller who has to decide whether
the value of the argument needs to be checked before being passed to the
callee. Because the caller has enough information to:

1. Decide whether the check is necessary at all.

2. Perform the check in a thorough manner.

Note that the specification of the standard C library doesn't require
such checks and few (if any) actual implementations perform them. For
the reasons described above.

Dan
 
S

Severian

It saves a lot of finger-pointing and having to prove things -- even
in some cases when I'm both the finger-pointer and -pointee!
Indeed. Checking for bad args makes sense only if it can be done in
a thorough manner and if the function specification promises such checks.

In one library I wrote (more detail below), I check a specific pointer
for:

1. NULL pointer.
2. On platforms where the check is available and inexpensive: writable
data at the address, and at address + structure length - 1.
3. Valid contents in some key portions of the structure.
Furthermore, these checks are not free. Why penalise the performance
of the correct programs, that never pass bad arguments, for the sake of
the broken programs, that do? It is the caller who has to decide whether
the value of the argument needs to be checked before being passed to the
callee. Because the caller has enough information to:

1. Decide whether the check is necessary at all.

2. Perform the check in a thorough manner.

Sometimes only the callee has the information necessary for either. In
a database layer I wrote (and use regulary), a context block is
returned to the caller when the database is opened, somewhat analogous
to a FILE *. The caller uses this context block in subsequent calls
for database access.

Since the caller has no knowledge of the layout or contents of the
context block, each externally-callable routine in my library
validates it -- not completely thoroughly (see above), but well enough
that most possible problems are detected early. This helps when a bug
does occur; rather than some obscure crash deep within the bowels of
the database software, the library returns an error immediately.
Note that the specification of the standard C library doesn't require
such checks and few (if any) actual implementations perform them. For
the reasons described above.

For me, it depends on the scope of the library. The more complex the
library (and the more libraries it is in turn depenent upon), the more
likely that errors caused by bad arguments will be difficult to track
down, especially in multi-threaded or asynchronous operation. And, at
least in my example case, the cost of the validation is essentially
unmeasurable, since the functions themselves are so much more
expensive.

Of course, in many other libraries I've written, I perform no argument
validation at all. It always depends!

- Sev
 
S

Severian

Michael B Allen said:
I have a general purpose library that has a lot of checks for bad input
parameters like:
[snip]

The only problem I can see is if one of your functions calls another
one of your functions and both of them check for bad input, so you
might be testing for the same kind of invalid input twice.

In a case where I feel that argument validation is imperative, only
the calls availble externally perform validation; internally, the
library doesn't ever call those routines.

- Sev
 
G

goose

Joona I Palaste said:
Irrwahn Grausewitz said:
[Please keep some context, including attributions, when replying; it
makes it much easier for others to follow discussions. Thank you.]
Stop fighting kids. I'm sure you're all talented programmers but the way how
some people deal with each other is horrible. Get off that computer and
learn some basic social stuff first, that's what makes us differ from
animals.
Neither of them is a kid. And E.R.T. is a well known troll who
regularly alters quoted text without indication, in order to mess
up usenet discussions. That's not just a Bad Thing[tm], it's
abusive behaviour.
My 0.02 EUR.

But he didn't call them kids. He asked them to stop fighting kids. I
think that's wise. After all, the kids are hardly a match for them,
are they?

it depends; are they having a battle of the wits with kids, or
physical fighting ?

goose,
some usenet posters I know are no match for some
of the kids I know, in wit(less) battles :)
 
G

goose

Alan Balmer said:
Irrwahn Grausewitz said:
[Please keep some context, including attributions, when replying; it
makes it much easier for others to follow discussions. Thank you.]
Stop fighting kids. I'm sure you're all talented programmers but the way how
some people deal with each other is horrible. Get off that computer and
learn some basic social stuff first, that's what makes us differ from
animals.
Neither of them is a kid. And E.R.T. is a well known troll who
regularly alters quoted text without indication, in order to mess
up usenet discussions. That's not just a Bad Thing[tm], it's
abusive behaviour.
My 0.02 EUR.

But he didn't call them kids. He asked them to stop fighting kids. I
think that's wise. After all, the kids are hardly a match for them,
are they?

But talented programmers have to do *something* for relaxation! You
have to admit that fighting kids is basic social stuff, after all, and
it does get one off the computer. I'm not so sure it differentiates us
from animals, though. Most of us actually are animals, though there
may be some vegetative tendencies here and there.

handy rule: if you start leaning towards sunlight, its time
for more meat in your diet :)

goose,
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top