A
arnuld
They *require* that the argument (for example, the argument to strlen())
is a pointer to a string.
The idea that a null pointer is not a pointer to a string is implicit in
the Standard's definition of the phrase "pointer to a string" (C99
7.1.1p1).
Just checked it out and its says:
"A pointer to a string is a pointer to its initial (lowest addressed)
character."
Here is what I get:
#include <stdio.h>
int main(void)
{
const char* arrc = "clc";
const char* p = arrc;
for(; *p; ++p)
{
printf("p: %p\n", (void*)p);
}
return 0;
}
================ OUTPUT ========================
[arnuld@dune programs]$ gcc -ansi -pedantic -Wall -Wextra test.c
[arnuld@dune programs]$ ./a.out
p: 0x80484b0
p: 0x80484b1
p: 0x80484b2
[arnuld@dune programs]$
of course, lowest adressed character is first one, element on index
zero). I remember one of my colleagues telling me that array elements
need not be in ascending order of addresses, they can be in descending
order of addresses e.g. in my example, it could print 4b2, 4b1, 4b0.
There is not guarantee that elements are always laid down in ascending
order in RAM (memory). From what you say I think he was wrong (if I get
correctly what Standard say). Any enlightenment here ?
There's no need for strlen() to make that distinction itself. It's
entirely the responsibility of the caller, just as it's the caller's
responsibility not to call strlen() with a pointer that's just been
free()'d.
A pointer value may be valid or invalid depending on the context in
which it's used. A null pointer value is perfectly valid on the RHS of
an assignment, but not as the operand of a unary "*". A pointer to a
struct object that's been converted to void* is valid as an argument to
memset(), but not as an argument to strlen().
I suppose that having string functions treat null pointers as if they
were pointers to empty strings would be more convenient in some cases
(though it could impose extra overhead where the caller has taken care
to pass a non-null pointer), but in my opinion it makes for a more
consistent mental model.
If you had a function that took an int* argument, would you want it to
treat a null pointer as if it pointed to an int with the value 0?
Admittedly, the difference there is that you can pass int arguments
directly, so there's no need to use a pointer if you just want the
value. If C were able to treat strings as first-class objects (as some
languages do), we probably wouldn't be having this debate.