N
Nick Keighley
I would have developed Go.
in what?
I would have developed Go.
static void
trim (char **ts)
{
unsigned char *exam;
unsigned char *keep;
if (!*ts) {
errno = EINVAL;
printf ("trim: %s\n", strerror (errno));
return;
}
exam = (unsigned char *) *ts;
while (isspace (*exam)) {
++exam;
}
*ts = (char *) exam;
if (!*exam) {
return;
}
keep = exam;
while (*++exam) {
if (!isspace (*exam)) {
keep = exam;
}
}
if (*++keep) {
*keep = '\0';
}
}
Anyone see bugs? It's not a trick question, I use this code. Just
wondering if I overlooked anything.
Keith Thompson said:Ben Bacarisse said:BruceS said:... Ignoring all the other problems
with this idea, is it actually possible to have no 0 anywhere in
memory?
Well, either argc must == 0 or argv[0] must be a null-terminated string
giving the program name or argv[0][0] must be a null character. Of
course, there is no guarantee that this zero can be found by repeated
manipulation of an unrelated pointer.
Ah, but all-bits-zero is only *a* representation of 0, not
necessarily the *only* representation of 0.
Suppose argc == 0, but the system uses a 1's-complement
representation and the value stored in argc is represented as
all-bits-1.
errno is 0 at program startup, but the same thing applies.
Nick Keighley said:here's my attempt
static char *trim (char *result, const char *input)
{
const char *start;
const char *end;
size_t result_length;
assert (result != NULL);
assert (input != NULL);
for (start = input; *start != '\0' && isspace (*start); start++)
continue;
for (end = input + strlen (input) - 1; end > start && isspace
(*end); end--)
continue;
result_length = end - start + 1;
if (result_length > 0)
{
memcpy (result, start,result_length);
*(result + result_length) = '\0';
}
else
*result = '\0';
That's a bit belt-and-braces since isspace('\0') is false.
Also there
is the issue of signed chars. You need isspace((unsigned char)*start)
to stay the right side of the law.
That's undefined when the original string is empty.
This seems rather wordy -- the two arms do the same thing.
doh!
Did you mean to use memmove here, or are your users warned that they
can't pass the same pointer in both argument positions? I'd either use
memmove or I'd 'restrict' qualify the pointers so the prototype withh do
the warning for me.
[1] I suspect there is another flaw in my reasoning since it is probably
possible that padding bits cold be peppered about the representation.
For example, int might be 4 bytes with only 28 value bits -- the
low-order 7 bits from each byte. There would then be lots of ways for
no byte to be zero no matter how many int zeros there were in the data.
In C99 you can work backwards. The XXX_MAX macros let you determine the
number of padding bits in the XXX type.
errno highlights the absurdity of the original project.
[1] I suspect there is another flaw in my reasoning since it is probably
possible that padding bits cold be peppered about the representation.
For example, int might be 4 bytes with only 28 value bits -- the
low-order 7 bits from each byte. There would then be lots of ways for
no byte to be zero no matter how many int zeros there were in the data.
That contradicts your earlier helpful advice:
Realistically, of course, there's almost certain to be a zero byte
*somewhere* in memory -- not that it matters.
OK, it's "almost" certain.
John Kelly said:[1] I suspect there is another flaw in my reasoning since it is probably
possible that padding bits cold be peppered about the representation.
For example, int might be 4 bytes with only 28 value bits -- the
low-order 7 bits from each byte. There would then be lots of ways for
no byte to be zero no matter how many int zeros there were in the data.
That contradicts your earlier helpful advice:
In C99 you can work backwards. The XXX_MAX macros let you determine the
number of padding bits in the XXX type.
[1] I suspect there is another flaw in my reasoning since it is probably
possible that padding bits cold be peppered about the representation.
For example, int might be 4 bytes with only 28 value bits -- the
low-order 7 bits from each byte. There would then be lots of ways for
no byte to be zero no matter how many int zeros there were in the data.
For a given signed type t, sizeof(t) * CHAR_BIT gives you the
total number of bits (include value bits, padding bits if any,
and the single sign bit), and you can compute the number of value
bits from T_MAX.
But you can't derive a mask for the padding bits. You have no standard
method of knowing where they are. That's a hole in the standard.
John Kelly said:On Fri, 27 Aug 2010 13:45:32 +0100, Ben Bacarisse wrote:
[1] I suspect there is another flaw in my reasoning since it is probably
possible that padding bits cold be peppered about the representation.
For example, int might be 4 bytes with only 28 value bits -- the
low-order 7 bits from each byte. There would then be lots of ways for
no byte to be zero no matter how many int zeros there were in the data.For a given signed type t, sizeof(t) * CHAR_BIT gives you the
total number of bits (include value bits, padding bits if any,
and the single sign bit), and you can compute the number of value
bits from T_MAX.
But you can't derive a mask for the padding bits. You have no standard
method of knowing where they are. That's a hole in the standard.
And maybe not even then.I consider it a mistake to define any new functions with errno as their
error-reporting mechanism, unless you are the kernel or libc implementor.
A minor point: OpenSSL doesn't _set_ errno to indicate its errors; itLook at some higher-level libraries and how they handle error codes. Most of
them don't touch errno. zlib, BerkeleyDB, and OpenSSL all have error codes,
but they leave errno alone.
Even getaddrinfo(), as a fresh addition to libc, didn't mess with errno. It
returns an error code and provides a separate gai_strerror() to map the error
code to a string.
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.