Re: Segfault City




"lovecreatesbeauty" <lovecreatesbeauty@xxxxxxxxx> wrote

Richard Heathfield wrote:
Malcolm said:
int chartonumber( char ch)
{
assert( isdigit(ch) );
return ch - '0';
}
Nice, easy to see. And if someone passes a non-digit to such a
function,
it deserves to kick.
And no, it isn't qute conforming but it's conforming enough. Anyone
care
to point out the technical difficulty?
My pleasure.

Richard, I will ask for your help on following my code snippet. It will
be my pleasure again to read anyone's comments on it.

int ctoi(char c)
{
int i = -1;
if (c >= '0' && c <= '9')
{
i = c - '0';
}
return i;
}

Firstly, it won't kick if NDEBUG is defined. Secondly, if ch is not
representable as an unsigned char, the behaviour is undefined.

I remember someone ever said that there is not release or debug version
in C language. The C language (preprocessor) has Macros, functions. A
particular user (library) function is not a part of the features the C
language. I do not think there is differences between the assert() and
a simple if statement.

To ask for the integer value of '~' or 'x' or any non-digit is nonsense.
The question is, what do we want the function to do if that happens?

It depnds what you are doing. if you are writing a video game there is
argument for returning zero and hoping for the best - the worst thing that
can happen is that the game craches anyway, probably you'll just get a tiny
error on screen most players won't notice.
If you are doing accounts software, on the other hand, the last thing you
want is for a wrong value to get into your database. Better far to trigger
an error.
If you are writing software for a life support machine?

assert() is the C way of checking parameters. It always triggers an error
under debug conditions, which is what you want.

Here's how Edward Nilges uses his function


// -----------------------------------------------------------------------
// Convert a string containing an unsigned number to its value: return
// true (-1) on success or false (0) on failure
//
//
// This function returns false when the number's value overflows, but in
// this case, its reference parameter intValue is still returned. In
// this case the value will be negative.
//
//
int string2Number( char *strInstring, int *intValue )
{
int intIndex1;
int intCharValue;
for ( intIndex1 = 0, *intValue = 0;
intIndex1 < strlen( strInstring );
intIndex1++ )
{ intCharValue = char2Number(strInstring[intIndex1]);
if ( intCharValue < 0 ) return 0;
*intValue = *intValue * 10 + intCharValue;
if ( *intValue < 0 ) return 0; }
return -1;
}

Here's how the higher-level function is called

if ( intArgCount < 3
||
! string2Number(strArgValues[1], &intStart)
||
! string2Number(strArgValues[2], &intFinish) )
{
printf( "Syntax: %s\n", SYNTAX_REMINDER );
return -1;
}




It is not terrible code, but the difficulties in reading it mount as error
returns are propagated upwards. One function returns a negative number on
error, another returns zero. Fortunately the program is short enough for
this not to really matter.
Most importantly, every call has an error check anyway. So why not make the
check validate the parameters rather than test the return?




--
Buy my book 12 Common Atheist Arguments (refuted)
$1.25 download or $7.20 paper, available www.lulu.com/bgy1mm


.



Relevant Pages