'\0' ?

S

Skybuck Flying

Hi,

I have a question about \0

This is the implementation of strcmp in glibc.

Which is probably the same on many other compilers/libraries.

My question is about this:

if (c1 == '\0')

What does '\0' mean ?

Is that a null terminated character ?

Does that mean strcmp stops comparing as soon as it encounters a null
terminated character ?


#include <string.h>
#include <memcopy.h>

#undef strcmp

/* Compare S1 and S2, returning less than, equal to or
greater than zero if S1 is lexicographically less than,
equal to or greater than S2. */
int
strcmp (p1, p2)
const char *p1;
const char *p2;
{
register const unsigned char *s1 = (const unsigned char *) p1;
register const unsigned char *s2 = (const unsigned char *) p2;
unsigned reg_char c1, c2;

do
{
c1 = (unsigned char) *s1++;
c2 = (unsigned char) *s2++;
if (c1 == '\0')
return c1 - c2;
}
while (c1 == c2);

return c1 - c2;
}
libc_hidden_builtin_def (strcmp)

Bye,
Skybuck.
 
S

Steve Graegert

Skybuck said:
Hi,
[snip]

My question is about this:

if (c1 == '\0')

What does '\0' mean ?

Is that a null terminated character ?

It is _the_ null termination character.
Does that mean strcmp stops comparing as soon as it encounters a null
terminated character ?

Yes, it does. You can't compare strings beyond their end.
 
A

Al Bowers

Skybuck said:
Hi,

I have a question about \0

This is the implementation of strcmp in glibc.

Which is probably the same on many other compilers/libraries.

This implementation appears suspicious. Comment of the suspicious
code is below.
My question is about this:

if (c1 == '\0')

What does '\0' mean ?

Is that a null terminated character ?
Yes, it is the nul-terminating character which is required
to terminate all strings. THe Standard's definition of strcmp
does not mention the nul character but speaks in terms of
strings. Function strncmp is a different story.
Does that mean strcmp stops comparing as soon as it encounters a null
terminated character ?
Yes.



#include <string.h>
#include <memcopy.h>

#undef strcmp

/* Compare S1 and S2, returning less than, equal to or
greater than zero if S1 is lexicographically less than,
equal to or greater than S2. */
int
strcmp (p1, p2)
const char *p1;
const char *p2;
{
register const unsigned char *s1 = (const unsigned char *) p1;
register const unsigned char *s2 = (const unsigned char *) p2;
unsigned reg_char c1, c2;

do
{
c1 = (unsigned char) *s1++;
c2 = (unsigned char) *s2++;
if (c1 == '\0')
return c1 - c2;

if stored in s1 is '\0' then c1 would equal 0. c2 may be some
unsigned value, for example, 97.
So you have, for example, (unsigned)0 - (unsigned)97. Is is
possible or not possilbe for this to return a negative value
when converted to type int and returned from the function?
 
S

Shirish

if stored in s1 is '\0' then c1 would equal 0. c2 may be some
unsigned value, for example, 97.
So you have, for example, (unsigned)0 - (unsigned)97. Is is
possible or not possilbe for this to return a negative value
when converted to type int and returned from the function?

strcmp returns an integer and it just returns the difference between
ASCII values of c1 and c2. So, its quite possible that it returns a
negative value.

Shirish
http://www.cse.ohio-state.edu/~tatikond
 
M

Martin Ambuhl

Shirish wrote:

strcmp returns an integer and it just returns the difference between
ASCII values of c1 and c2. So, its quite possible that it returns a
negative value.

Sorry, no. There is no reason to believe that true apart from some
particular implementation on some particular platform. The standard
tells us

7.21.4.2 The strcmp function
Synopsis
#include <string.h>
int strcmp(const char *s1, const char *s2);
Description
The strcmp function compares the string pointed to by s1 to the
string pointed to by s2.
Returns
The strcmp function returns an integer greater than, equal to, or
less than zero, accordingly as the string pointed to by s1 is
greater than, equal to, or less than the string pointed to by s2.

Notice that there is no significance to the value returned apart from
its being <0, 0, or >0. ASCII is not part of the standard, and the
"difference between ASCII values" is an absurd interpretation of the
definition for, for example, implementations with non-ASCII encodings
such as EBCDIC or even implementations using ASCII but that consider
non-ASCII codes (>127) in the comparison.
 
S

Skybuck Flying

if stored in s1 is '\0' then c1 would equal 0. c2 may be some
unsigned value, for example, 97.
So you have, for example, (unsigned)0 - (unsigned)97. Is is
possible or not possilbe for this to return a negative value
when converted to type int and returned from the function?

Good question.

In delphi it returns a negative value which is ok.

In visual C/C++ 6.0 it returns a positive value which is probably wrong <-
ouch.

Congratulations I think you just found a bug :) You have a very sharp eye !
:)

// delphi:
var
a,b : byte;
c : integer;
begin
a := 0;
b := 97;
c := a - b;
ShowMessage(IntToStr(c)); // shows -97
end;

HOWEVER in Visual C/C++ 6.0 it goes horribly wrong I think:

int bla()
{
unsigned char a;
unsigned char b;

a = 0;
b = 97;

return (a-b);

}

int main()
{
printf("bla: %d", bla );
}

// output: bla: 4198405

Bye,
Skybuck.
 
J

Jason Creighton

[Al Bowers wrote:]
[Skybuck Flying wrote:]
#include <string.h>
#include <memcopy.h>

#undef strcmp

/* Compare S1 and S2, returning less than, equal to or
greater than zero if S1 is lexicographically less than,
equal to or greater than S2. */
int
strcmp (p1, p2)
const char *p1;
const char *p2;
{
register const unsigned char *s1 = (const unsigned char *) p1;
register const unsigned char *s2 = (const unsigned char *) p2;
unsigned reg_char c1, c2;

do
{
c1 = (unsigned char) *s1++;
c2 = (unsigned char) *s2++;
if (c1 == '\0')
return c1 - c2;

if stored in s1 is '\0' then c1 would equal 0. c2 may be some
unsigned value, for example, 97.
So you have, for example, (unsigned)0 - (unsigned)97. Is is
possible or not possilbe for this to return a negative value
when converted to type int and returned from the function?

Good question.

In delphi it returns a negative value which is ok.

Delphi really doesn't have much to do with C...
In visual C/C++ 6.0 it returns a positive value which is probably
wrong <- ouch.

Congratulations I think you just found a bug :) You have a very sharp
eye ! :)

As I understand C, Visual C/C++ 6.0's behavior is conforming to the
standard and not a bug.
// delphi:
var
a,b : byte;
c : integer;
begin
a := 0;
b := 97;
c := a - b;
ShowMessage(IntToStr(c)); // shows -97
end;

HOWEVER in Visual C/C++ 6.0 it goes horribly wrong I think:

int bla()
{
unsigned char a;
unsigned char b;

a = 0;
b = 97;

return (a-b);

}

int main()
{
printf("bla: %d", bla );
}

// output: bla: 4198405

You probably meant:

printf("bla: %d", bla());

As your code stands, you don't actually call the function, the value
you're seeing is a function pointer. (Standards guys: Right? In that
context, it will always be converted to a function pointer, right? Or
maybe not. But in any case, it's *not* the return value of the
function.)

Jason Creighton
 

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,769
Messages
2,569,582
Members
45,070
Latest member
BiogenixGummies

Latest Threads

Top