NULL to strlen function

C

Christopher Benson-Manica

Return WHAT?
Perhaps 0, so the caller is led to believe that there is an empty
string?

That would be the best option. errno could also be set, but that
would really complicate matters for most strlen() clients.
 
S

Serve Laurijssen

Strlen expects a string as an argument. Is a NULL pointer a string?
(Hint: this is a rhetorical question).

thats a bit silly really, it's just a matter of implementation
I dont know exactly what the standard says, but at least it was decided at
some point that strcpy does not accept NULL or at the very least does not
have to. They might as well just have chosen to let the string functions do
nothing when being passed NULL.

Or take this example:
char *p = NULL;
free(p);

is p a valid pointer returned from malloc,calloc or realloc? well no, but
for free it was decided to let it accept that
 
S

Stephen Sprunk

Clark S. Cox III said:
Other than assert'ing that the parameter is non-NULL, what would you
consider a reasonable way for strlen to deal with NULL?

strlen(NULL) == 0 on some implementations. That might be considered
reasonable, depending on who you ask.
If I find a platform where that assumption doesn't hold, then, as I
said
above, I won't rely on it. The last platform on which I did any
extensive coding that didn't, upon a read from NULL, cause programs to
immediately crash, interrupt, drop into a debugger, etc. was the old
(i.e. pre MacOSX, pre-VM) MacOS. However, even there, it was a simple
matter to configure the debugger to watch for access to that memory
location.

This is actually near and dear to my heart, because I wrote my first C
program on AIX. All of the str* functions failed silently when passed
NULL, so I grew to rely on that behavior. When I then tried running the
same code on Linux, I ended up spending hours adding in NULL checks
because glibc would segfault, unlike AIX's libc. It was an eye-opening
experience for me about assuming what's portable in C. Luckily for me,
I encountered this on my very first program (okay, so my "hello world"
used sockets and Motif, but still...) so I didn't let that "whatever
works on my system should work anywhere" mentality that many C novices
seem to develop.

I'd prefer a happy medium -- a debug build that assert()ed whenever I
did something stupid, but also a release build that would make an
attempt to do something sane and thus not crash on the user...

S
 
K

Keith Thompson

David T. Ashley said:
A NULL pointer and a string of length zero are not the same thing.

The phrase "NULL pointer" is just *slightly* misleading. The correct
term is "null pointer".

NULL is a macro defined in <stddef.h> and several other standard
headers. It expands to an implementation-defined "null pointer
constant". A "null pointer constant" and a "null pointer" are two
very different things; the former is a construct that can appear in a
C source file, and the latter is a value that can exist during
execution of a program. You typically use a null pointer constant to
obtain a null pointer at run time (which is why the name "null pointer
constant" contains the phrase "null pointer"), but it can be important
to keep the distinction in mind.
A NULL pointer traditionally has the value of 0, which is usually an
unsuitable pointer; but in any case it is a reserved value defined
to be a non-functional pointer.

A literal 0 is by definition a null pointer constant. A null pointer
value may or may not be represented as all-bits-zero. Section 5 of
the comp.lang.c FAQ, <http://www.c-faq.com/>, covers this very well.

[...]
 
D

Default User

Serve said:
thats a bit silly really, it's just a matter of implementation

No, a matter of definition.
I dont know exactly what the standard says, but at least it was
decided at some point that strcpy does not accept NULL or at the very
least does not have to.

We are discussing strlen(). The standard wording for that has been
posted. Some other string functions may generate a different discussion.
They might as well just have chosen to let
the string functions do nothing when being passed NULL.

What does "do nothing" mean to you? strlen() has to return a value, so
"nothing" not really an option.
Or take this example:
char *p = NULL;
free(p);

is p a valid pointer returned from malloc,calloc or realloc? well no,
but for free it was decided to let it accept that


free() does not return a value, so it can indeed "do nothing".




Brian
 
K

Keith Thompson

Strlen expects a string as an argument. Is a NULL pointer a string?
(Hint: this is a rhetorical question).

No, strlen expected a pointer to a string as an argument. (And a null
pointer does not point to a string.)
 
S

SM Ryan

# Is it that strlen function can't handle NULL pointers?

No, it doesn't. You can define your own string length function which does.
 
J

JimS

strlen(NULL) == 0 on some implementations. That might be considered
reasonable, depending on who you ask.


This is actually near and dear to my heart, because I wrote my first C
program on AIX. All of the str* functions failed silently when passed
NULL, so I grew to rely on that behavior. When I then tried running the
same code on Linux, I ended up spending hours adding in NULL checks
because glibc would segfault, unlike AIX's libc. It was an eye-opening
experience for me about assuming what's portable in C. Luckily for me,
I encountered this on my very first program (okay, so my "hello world"
used sockets and Motif, but still...) so I didn't let that "whatever
works on my system should work anywhere" mentality that many C novices
seem to develop.

I'd prefer a happy medium -- a debug build that assert()ed whenever I
did something stupid, but also a release build that would make an
attempt to do something sane and thus not crash on the user...

S

The C library I'm using has 2 versions, a debug and a release one.
When I'm developing I use the debug library. It does

size_t strlen(const char *s)
{
assert(s != NULL);
...
}

Jim
 
C

CBFalconer

Strlen expects a string as an argument. Is a NULL pointer a string?
(Hint: this is a rhetorical question).

To be slightly more accurate, strlen expects a pointer to a
string. Does NULL point to a string.
 
G

Gordon Burditt

Other than assert'ing that the parameter is non-NULL, what would you
To me, it wouldn't strike me as unreasonable for strlen(NULL) to
return 0.

To me, it wouldn't strike me as unreasonable for strlen(NULL) to
run:
while(1) {
abort();
}

The bug gets identified quickly. However, this is not recommended
for safety-critical software *in production* such as flight control,
where "crash" has a very different meaning.
I presume the reasons that it doesn't are a) performance, and
b) not all the other str* functions could have reasonable behavior
when passed NULL, so none of them do.

Some str* functions *DO* have defined behavior when passed NULL
instead of a string. Example: the first argument of strtok().
 
B

Barry Schwarz

# Is it that strlen function can't handle NULL pointers?

No, it doesn't. You can define your own string length function which does.

Yes but you can't call it strlen if it has external linkage since that
name is reserved.


Remove del for email
 
B

Barry Schwarz

Hi Everyone,

I tried the following program unit in Microsoft Visual c++ 6.0 and the
program caused unexpected behavior,

On the contrary, the program did exactly what you should have
expected.
#include <stdio.h>
#include <string.h>

int main()
{
char *p;
p = NULL;
printf("%d\n",strlen(p));

This statement invokes undefined behavior. Anything your program does
at this point is not unexpected or perhaps it should be phrased that
at this point you are no longer entitled to have any expectations.
}

Is it that strlen function can't handle NULL pointers?

Yes but. Even if some compiler included a strlen function in its run
time library that did handle NULL pointers, the standard still states
the behavior is undefined.


Remove del for email
 
J

jaysome

To me, it wouldn't strike me as unreasonable for strlen(NULL) to
run:
while(1) {
abort();
}

The bug gets identified quickly. However, this is not recommended
for safety-critical software *in production* such as flight control,
where "crash" has a very different meaning.

I disagree. It should be recommended.

That's because strlen(NULL) results in undefined behavior, and you
should have caught such an error during verification, way before the
software gets into *production* (especially with safety-critical
software).

If not, then what you are saying is that it's better to rely on the
results of undefined behavior of strlen(NULL) and all it's perverse
consequences than to rely on the "crash"?

Best regards
 
D

Dik T. Winter

> I dont know exactly what the standard says, but at least it was decided at
> some point that strcpy does not accept NULL or at the very least does not
> have to. They might as well just have chosen to let the string functions do
> nothing when being passed NULL.

How about
strcmp(NULL, "")
?
 
S

Stephen Sprunk

jaysome said:
I disagree. It should be recommended.

That's because strlen(NULL) results in undefined behavior, and you
should have caught such an error during verification, way before the
software gets into *production* (especially with safety-critical
software).

One can never test every possible condition in complex real-world
software, and the consequences of your validation being incomplete are
too severe to risk a crash no matter how sure you are you got it right.
Trying to do _something_ reasonable at least has the _chance_ of saving
lives; crashing leaves no chance at all. Deliberately choosing to kill
people is likely to bankrupt you, if not put you in jail.

Pedantism is for those who don't have to face the consequences, or those
whose work doesn't matter.
If not, then what you are saying is that it's better to rely on the
results of undefined behavior of strlen(NULL) and all it's perverse
consequences than to rely on the "crash"?

Yes.

Imagine a hypothetical 911* call center. Now, say there's a bug that
causes the agents' phones to crash randomly due to trapping on
strlen(NULL). It's one thing for that to be an accident, in which case
the phone vendor is likely to only face a few million dollars (per
victim) in fines and civil suits, but if it came out that the crash was
deliberate when there was the option of handling the error without
hanging up on someone who was being raped or assaulted, well, let's just
say juries wouldn't be very sympathetic to those responsible.

(And this isn't such a hypothetical example. I've seen it actually
happen to two different vendors, though NDAs prevent me from saying who
or when.)

S

* For those outside the US, replace with your local emergency services
number, e.g. 112 in Europe.
 
S

Serve Laurijssen

Dik T. Winter said:
How about
strcmp(NULL, "")

thats a good one. My intuition would say that they would compare unequal.
But thats impossible because would strcmp return <0 or >0? Now I see why it
was decided to not let the string functions have defined behaviour when
being passed NULL.
 
S

Stephen Sprunk

Serve Laurijssen said:
thats a good one. My intuition would say that they would compare
unequal.

Interesting. My intuition would be that -- assuming that the call
doesn't segfault -- it'd compare equal. That's the more logical thing
to me, since novice programmers don't see a difference between NULL and
"", and certain things get a lot simpler if you require that to be true.

The rest of the str* functions fall into line pretty well once you take
that stand, which is convenient (if you choose to define any of them for
NULL params).
But thats impossible because would strcmp return <0 or >0? Now I see
why it was decided to not let the string functions have defined
behaviour
when being passed NULL.

My guess is that, like many other things in C, the behavior prior to C89
was divergent, so ANSI decided it was better left undefined to avoid
forcing implementors to change their code.

S
 
S

Serve Laurijssen

Stephen Sprunk said:
Interesting. My intuition would be that -- assuming that the call doesn't
segfault -- it'd compare equal. That's the more logical thing to me,
since novice programmers don't see a difference between NULL and "", and
certain things get a lot simpler if you require that to be true.

So then this code would be accepted too:

struct Struct *astruct = ""; // since NULL is the same as ""

if (strcmp((const char *)astruct, "") == 0)
{
// etc
}

I dont know about you, but it's getting pretty scary to me :)
 
S

Stephen Sprunk

Serve Laurijssen said:
So then this code would be accepted too:

struct Struct *astruct = ""; // since NULL is the same as ""

Not the same in that sense, no. Saying strcmp(NULL,"") returns equality
is very different than saying NULL=="". The latter is necessarily
false; the former is allowed by the C standard since the behavior is
undefined.

S
 
S

Serve Laurijssen

Stephen Sprunk said:
Not the same in that sense, no. Saying strcmp(NULL,"") returns equality
is very different than saying NULL=="". The latter is necessarily false;
the former is allowed by the C standard since the behavior is undefined.

struct Struct *astruct = NULL;

suddenly this becomes a valid parameter to strcmp comparing equal to ""
 

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,774
Messages
2,569,598
Members
45,158
Latest member
Vinay_Kumar Nevatia
Top