Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Degenerate strcmp

Reply
Thread Tools

Degenerate strcmp

 
 
Chris Dollin
Guest
Posts: n/a
 
      08-20-2007
Keith Thompson wrote:

> Chris Dollin <(E-Mail Removed)> writes:


>> Doesn't the Standard says specifically that `strlen` takes a string?
>> If so, passing a char* that /isn't/ a string is undefined behaviour.
>> You don't have to think carefully about how to interpret the
>> return value; you have to ensure it's passed a string.

>
> No, it says that strlen takes a char* (actually a const char*).


It also says (at least it does in this C90 draft here) "... computes the
length of the string pointed to by s". The Hedgehog presumably counts
that as saying specifically that `strlen` takes a string (as opposed
to just any `char*` value).

--
Chris "presumptive, since mind-reading known to be unsound" Dollin

Hewlett-Packard Limited registered no:
registered office: Cain Road, Bracknell, Berks RG12 1HN 690597 England

 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      08-20-2007
Chris Dollin <(E-Mail Removed)> writes:
> Keith Thompson wrote:
>> Chris Dollin <(E-Mail Removed)> writes:
>>> Doesn't the Standard says specifically that `strlen` takes a string?
>>> If so, passing a char* that /isn't/ a string is undefined behaviour.
>>> You don't have to think carefully about how to interpret the
>>> return value; you have to ensure it's passed a string.

>>
>> No, it says that strlen takes a char* (actually a const char*).

>
> It also says (at least it does in this C90 draft here) "... computes the
> length of the string pointed to by s". The Hedgehog presumably counts
> that as saying specifically that `strlen` takes a string (as opposed
> to just any `char*` value).


No doubt. Unfortunately, the Hedgehog is mistaken (though I have no
doubt it was an innocent mistake). A pointer to a string is not a
string.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
 
 
 
Chris Dollin
Guest
Posts: n/a
 
      08-20-2007
Keith Thompson wrote:

> Chris Dollin <(E-Mail Removed)> writes:
>> Keith Thompson wrote:
>>> Chris Dollin <(E-Mail Removed)> writes:
>>>> Doesn't the Standard says specifically that `strlen` takes a string?
>>>> If so, passing a char* that /isn't/ a string is undefined behaviour.
>>>> You don't have to think carefully about how to interpret the
>>>> return value; you have to ensure it's passed a string.
>>>
>>> No, it says that strlen takes a char* (actually a const char*).

>>
>> It also says (at least it does in this C90 draft here) "... computes the
>> length of the string pointed to by s". The Hedgehog presumably counts
>> that as saying specifically that `strlen` takes a string (as opposed
>> to just any `char*` value).

>
> No doubt. Unfortunately, the Hedgehog is mistaken (though I have no
> doubt it was an innocent mistake). A pointer to a string is not a
> string.


My sloopiness. I forget that a string is the null-terminated-char-sequence
and tend to use "string" to mean pointer-to-ditto.

--
Pointer To Hedgehog
"Our future looks secure, but it's all out of our hands"
- Magenta, /Man and Machine/

 
Reply With Quote
 
Kenneth Brody
Guest
Posts: n/a
 
      08-20-2007
(E-Mail Removed) wrote:
>
> On 18 Aug 2007 at 21:59, Richard Tobin wrote:
> > In article <(E-Mail Removed)>,

[...]
> >>main() { printf("%d\n",strlen(malloc(0))); }

[...]
> > The C library functions are only required to behave correctly if you call
> > them correctly. If you call them with random data, all bets are off.
> > (In this particular case, it may well produce a segmentation fault, because
> > malloc(0) may return null.)

>
> No I believe malloc(0) can never return null - after all, how could it
> not be possible to allocate 0 bytes of memory!

[...]

What you believe is irrelevent. Quoting 7.20.3:

If the size of the space requested is zero, the behavior is
implementation defined: either a null pointer is returned, or
the behavior is as if the size were some nonzero value, except
that the returned pointer shall not be used to access an object.

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <(E-Mail Removed)>


 
Reply With Quote
 
Army1987
Guest
Posts: n/a
 
      08-20-2007
On Sat, 18 Aug 2007 11:19:49 +0200, Antoninus Twink wrote:

> main() { printf("%d\n",strlen(malloc(0))); }


Enumerating all of the reasons why this causes UB is left as an
exercise to the reader.
--
Army1987 (Replace "NOSPAM" with "email")
No-one ever won a game by resigning. -- S. Tartakower

 
Reply With Quote
 
Francine.Neary@googlemail.com
Guest
Posts: n/a
 
      08-20-2007
On Aug 20, 8:36 pm, Army1987 <(E-Mail Removed)> wrote:
> On Sat, 18 Aug 2007 11:19:49 +0200, Antoninus Twink wrote:
> > main() { printf("%d\n",strlen(malloc(0))); }

>
> Enumerating all of the reasons why this causes UB is left as an
> exercise to the reader.


I'll have a go:
1) Uses variadic function with no prototype in scope.
2) Whether or not malloc(0) returns null, it is UB to try to
dereference it, and strlen is going to dereference it all right...
3) ...and there's no reason to expect it to point to a string, as
strlen requires.
4) Uses %d as a format specifier for a size_t... though as the
compiler assumes that strlen (used without a prototype) returns an
int, maybe these two bugs cancel each other out.
5) Similarly, if the compiler assumes malloc returns int, and doesn't
know anything about strlen's arguments as there's no prototype around,
the conversion void * -> int -> char * is, I believe, implementation
defined.
6) Execution falls off the end of a non-void function without
returning a value.

> --
> Army1987 (Replace "NOSPAM" with "email")
> No-one ever won a game by resigning. -- S. Tartakower


 
Reply With Quote
 
Flash Gordon
Guest
Posts: n/a
 
      08-20-2007
(E-Mail Removed) wrote, On 20/08/07 21:04:
> On Aug 20, 8:36 pm, Army1987 <(E-Mail Removed)> wrote:
>> On Sat, 18 Aug 2007 11:19:49 +0200, Antoninus Twink wrote:
>>> main() { printf("%d\n",strlen(malloc(0))); }

>> Enumerating all of the reasons why this causes UB is left as an
>> exercise to the reader.

>
> I'll have a go:
> 1) Uses variadic function with no prototype in scope.
> 2) Whether or not malloc(0) returns null, it is UB to try to
> dereference it, and strlen is going to dereference it all right...
> 3) ...and there's no reason to expect it to point to a string, as
> strlen requires.
> 4) Uses %d as a format specifier for a size_t... though as the
> compiler assumes that strlen (used without a prototype) returns an
> int, maybe these two bugs cancel each other out.


No, they definitely produce one instance of UB for using a function
which does not return int without a prototype.

> 5) Similarly, if the compiler assumes malloc returns int, and doesn't
> know anything about strlen's arguments as there's no prototype around,
> the conversion void * -> int -> char * is, I believe, implementation
> defined.


No, because there is no prototype in scope for malloc and it does not
return an int calling it invokes UB.

Passing an int to strlen without a prototype in scope invokes UB (with
one in scope it requires a diagnostic.

No conversions were used.

> 6) Execution falls off the end of a non-void function without
> returning a value.


That returns an undefined status, some people argue it does not invoke
undefined behaviour.

>> --
>> Army1987 (Replace "NOSPAM" with "email")
>> No-one ever won a game by resigning. -- S. Tartakower


Please don't quote peoples signatures, the bit typically after the "-- "
unless you are actually quoting on them.
--
Flash Gordon
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      08-20-2007
(E-Mail Removed) writes:

> On Aug 20, 8:36 pm, Army1987 <(E-Mail Removed)> wrote:
>> On Sat, 18 Aug 2007 11:19:49 +0200, Antoninus Twink wrote:
>> > main() { printf("%d\n",strlen(malloc(0))); }

>>
>> Enumerating all of the reasons why this causes UB is left as an
>> exercise to the reader.

>
> 4) Uses %d as a format specifier for a size_t... though as the
> compiler assumes that strlen (used without a prototype) returns an
> int, maybe these two bugs cancel each other out.


I would say that the %d is not in error. The compiler will arrange
that the function called strlen will return an int and an int will be
printed (it might be trap representation, but that is because of the
*other* problem you identified).

I think it amusing that one of the few correct things about this
one-line program will have to change if the rest of it is corrected!

> 6) Execution falls off the end of a non-void function without
> returning a value.


You get to chose here. Falling off main is not a problem in C99 but
the implicit int in main's definition is -- take your pic based on
language standard.

--
Ben.
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      08-20-2007
Flash Gordon <(E-Mail Removed)> writes:
> (E-Mail Removed) wrote, On 20/08/07 21:04:
>> On Aug 20, 8:36 pm, Army1987 <(E-Mail Removed)> wrote:
>>> On Sat, 18 Aug 2007 11:19:49 +0200, Antoninus Twink wrote:
>>>> main() { printf("%d\n",strlen(malloc(0))); }
>>> Enumerating all of the reasons why this causes UB is left as an
>>> exercise to the reader.

[...]
>> 6) Execution falls off the end of a non-void function without
>> returning a value.

>
> That returns an undefined status, some people argue it does not invoke
> undefined behaviour.


In C90, it returns an undefined status. IMHO that's not undefined
behavior; it only affects the behavior of the environment, which is
outside the scope of the standard.

In C99, since the function in question is main, a special rule says
that falling off the end is equivalent to 'return 0;'. (But then, in
C99 the 'main()' declaration is a constraint violation.)

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      08-20-2007
Ben Bacarisse <(E-Mail Removed)> writes:
> (E-Mail Removed) writes:
>> On Aug 20, 8:36 pm, Army1987 <(E-Mail Removed)> wrote:
>>> On Sat, 18 Aug 2007 11:19:49 +0200, Antoninus Twink wrote:
>>> > main() { printf("%d\n",strlen(malloc(0))); }
>>>
>>> Enumerating all of the reasons why this causes UB is left as an
>>> exercise to the reader.

>>
>> 4) Uses %d as a format specifier for a size_t... though as the
>> compiler assumes that strlen (used without a prototype) returns an
>> int, maybe these two bugs cancel each other out.

>
> I would say that the %d is not in error. The compiler will arrange
> that the function called strlen will return an int and an int will be
> printed (it might be trap representation, but that is because of the
> *other* problem you identified).


Not necesarily. strlen actually returns a size_t. Calling it as if
it returned an int (regardless of what's done with the result) invokes
undefined behavior. One of the infinitely many possible consequences
of this undefined behavior is that the compiler uses its knowledge of
the standard library and treats strlen as if it returned a size_t
(which, of course, it does). Passing this size_t to printf with a
"%d" format invokes UB again (and the compiler could pretend that the
format is really "%zu"). This would be overly helpful in my opinion
(if I make a mistake, I want the compiler to tell me about it, not to
fix it), but it's legal.

[...]

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
segfault when strcmp Robert Mens C Programming 6 10-23-2003 02:53 AM
strcmp muser C++ 6 10-09-2003 08:18 AM
strcmp problem Shane Peck C++ 6 09-22-2003 05:44 PM
strcmp but with '\n' as the terrminator Allan Bruce C Programming 53 07-30-2003 07:38 PM
please help with strcmp() Andrej Hocevar C Programming 3 07-19-2003 04:41 PM



Advertisments