When I call the standard strncpy function, I provide it a negative
argument,
such as:
strncpy(s, ct, -1)
Here -1 is converted to the type size_t which is an unsigned integer.
Thus this actually results in strncpy receiving a very large positive
value. The segmentation fault is probably caused by strncpy trying to
read memory far beyond the legal limits.
I compile the code with gcc, when I run, it says "Segmentation fault".
Do you think it's ok? I try this to see how the library handle invalid
parameter.
In C each function is documented clearly as to what type of values it
accepts. In addition to this there are situations where many values do
not make any sense.
In general the programmer has to be careful to pass the correct type and
range of values to the Standard library function.
When I define my own function, should I handle this kind of argument?
It's a matter of trade-off. It's very common nowadays to sacrifice a
minuscule amount of runtime efficiency to check for common exceptions
like invalid arguments.
Nevertheless there are many situations where such checks are either
inappropriate or not possible, not least of which is the situation
where the callee has no idea if an argument is a valid value. Such
information belongs to the caller. Library function generally blindly
accept the arguments that they are given barring a few elementary check
like null pointer values, checking for values outside the accepted
domain etc.
And if so, how can I tell the caller the argument is wrong?
By setting some kind of error indicator. I generally return a status
value where this is convenient. Otherwise I treat one of the arguments
as a pointer to an object which receives the status value. I usually
don't use global objects like errno.
Return some error code such as -1?
Yes. However designing proper error codes is not a trivial task and
changing things retrospectively is often difficult. Also use symbolic
constants instead of literals.
But how about the function return type is void?
Then the function either has to set an external object, or access an
object through one of it's arguments or invoke a callback function, or
raise a signal or...
Clearly there are numerous ways. Which one is appropriate for a given
function is very dependent on the function's details and related
context.
I know in Java, I can define some invalid parameter exception to
indicate this.
What can I do with C?
C doesn't have standardised support for exceptions so unless your
willing to simulate them, the usual method is to rely on explicit
checking of status values each time the function is invoked. Wrappers
can encapsulate and abstract these details to a large extent.