Difference between '\0' and 0

A

August Karlstrom

Hello all,

If c is a char then is there any difference between

c = '\0'

and

c = 0

?


Regards,
August
 
P

pete

August said:
Hello all,

If c is a char then is there any difference between

c = '\0'

and

c = 0

?

It doesn't matter what c is.
'\0' and 0 are both constant primary expressions
of type int and value zero.
 
Y

yohji

August said:
Hello all,

If c is a char then is there any difference between

c = '\0'

and

c = 0

?


Regards,
August
Er,in fact,in C, a char is an 8-bit integer(not all).The ASCII value of
'\0' is 0.So c='\0' equals to c=0 .In many programs,we use char instead
of int when the integer is small.
 
A

August Karlstrom

pete said:
It doesn't matter what c is.
'\0' and 0 are both constant primary expressions
of type int and value zero.

The Lint program Splint thinks there is a difference:

$ cat test.c
int main(void)
{
char c;

c = '\0';
c = 0;
return 0;
}
$ splint test.c
Splint 3.1.1 --- 15 Jun 2004

test.c: (in function main)
test.c:6:4: Assignment of int to char: c = 0
Types are incompatible. (Use -type to inhibit warning)

Finished checking --- 1 code warning


-- August
 
M

Martin Ambuhl

yohji said:
Er,in fact,in C, a char is an 8-bit integer(not all).The ASCII value of
'\0' is 0.So c='\0' equals to c=0 .In many programs,we use char instead
of int when the integer is small.

1) In fact, '\0' is an int, not a char, so it the question of chars
doesn't enter into the question.

2) In fact, a char is *not* an 8-bit integer. It is an integral type
capable of representing one of the two ranges CHAR_MIN to CHAR_MAX (if
char is signed) or 0 to UCHAR_MAX (if char is unsigned). The minimum
size on a binary machine to be able to meet that for the minimal
requirements of the standard is 8 bits.

3) In fact, the ASCII value of anything is irrelevant in comp.lang.c,
where we expect programs to be appropriate for any environment that
meets the requirements for the source and execution character sets in
the corresponding contexts. There is nothing special about ASCII, which
is only one of many encodings.
 
M

Malcolm

August Karlstrom said:
The Lint program Splint thinks there is a difference:

test.c:6:4: Assignment of int to char: c = 0
Types are incompatible. (Use -type to inhibit warning)
Lint is of limited value. '\0' is the character constant NUL that represents
a terminated string, whilst 0 is the integer value of nothing. However '\0'
== 0 is guaranteed to be true.
In fact use of a four character sequence doesn't add much to program
readbility, and may detract from it. Most code uses plain 0. It is also
quite common to see the construct

while(*str)
{
/* some code */
str++;
}

If you want strict type control, use a different language to C. C written to
make lint happy tends to be C that is hard to read.
 
L

Lawrence Kirby

1) In fact, '\0' is an int, not a char, so it the question of chars
doesn't enter into the question.

2) In fact, a char is *not* an 8-bit integer. It is an integral type
capable of representing one of the two ranges CHAR_MIN to CHAR_MAX (if
char is signed)

It is CHAR_MIN to CHAR_MAX whether char is signed or unsigned. This
corresponds to SCHAR_MIN to SCHAR_MAX when char is signed.

Lawrence
 
A

August Karlstrom

Malcolm said:
Lint is of limited value. '\0' is the character constant NUL that represents
a terminated string, whilst 0 is the integer value of nothing.

(The literal 0 can also denote the nil pointer)
However '\0' == 0 is guaranteed to be true.
In fact use of a four character sequence doesn't add much to program
readbility, and may detract from it. Most code uses plain 0. It is also
quite common to see the construct

while(*str)
{
/* some code */
str++;
}

If you want strict type control, use a different language to C. C written to
make lint happy tends to be C that is hard to read.

Ok, I tend to agree.


-- August
 
D

Dik T. Winter

> $ cat test.c
> int main(void)
> {
> char c;
>
> c = '\0';
> c = 0;
> return 0;
> }
> $ splint test.c
> Splint 3.1.1 --- 15 Jun 2004
>
> test.c: (in function main)
> test.c:6:4: Assignment of int to char: c = 0
> Types are incompatible. (Use -type to inhibit warning)

It is a bug that it does not complain about c = '\0'. In that case the
types are also "incompatible". But the mindset of the writers can be
deduced from the following in the known bugs file:
Pre-processing ISO8859-1 characters
Splint does not process ISO8859-1 characters correctly since it is
building on a pre-ISO8859-1 version of gcc's pre-processor, and
character \377 is indistinguishable from EOF.

'\377' is an intr with value 255, so quite distinguishable from EOF, which
is also an int. The conclusion is that Splint does not handle character
constants correctly.
 
K

Keith Thompson

August Karlstrom said:
The Lint program Splint thinks there is a difference:

$ cat test.c
int main(void)
{
char c;

c = '\0';
c = 0;
return 0;
}
$ splint test.c
Splint 3.1.1 --- 15 Jun 2004

test.c: (in function main)
test.c:6:4: Assignment of int to char: c = 0
Types are incompatible. (Use -type to inhibit warning)

Finished checking --- 1 code warning

The difference is only stylistic; there is absolutely no difference as
far as the language is concerned. I consider
c = '\0';
to be clearer than
c = 0;
because it implies to the reader (though not to the compiler) that a
character value is being assigned. Apparently the authors of splint
felt the same way.

Since a character constant, unlike an integer constant, normally can't
have a value outside the range of type char, it's not unreasonable for
splint to treat it as being of type char. But since even a reference
to a char object:
char c = '\0';
char x = c;
is promoted to int before being converted back to char, it's difficult
to know just what's going to keep splint from complaining.
 
R

Robert Gamble

August said:
(The literal 0 can also denote the nil pointer)

A nil pointer? Perhaps you mean NULL pointer constant, but this would
not apply to type char which is being discussed here...

Rob Gamble
 
A

August Karlstrom

Robert said:
A nil pointer? Perhaps you mean NULL pointer constant, but this would
not apply to type char which is being discussed here...

I used "nil pointer" to emphasize the distinction between the "points to
nothing" concept and the C macro constant NULL. In Oberon for instance,
NIL is a keyword (typeless constant) used for pointers and variables of
procedure type.

-- August
 
E

Emmanuel Delahaye

August Karlstrom wrote on 29/05/05 :
The Lint program Splint thinks there is a difference:
int main(void)
{
char c;

c = '\0';
c = 0;
return 0;
}
$ splint test.c
Splint 3.1.1 --- 15 Jun 2004

test.c: (in function main)
test.c:6:4: Assignment of int to char: c = 0
Types are incompatible. (Use -type to inhibit warning)

Finished checking --- 1 code warning

It's true that and int is not a char. Why in the world are you using a
char ? The cases where a single char is necessary are extremely rare
(only scanf("%c", &c) comes to my mind, and scanf() is not a
recommended function...)

That said, Lint seems to consider that '\0' is a char that is wrong in
C. (Or maybe, Lint is checking in C++ mode, in that case 0 is an int
and '\0' is a char). Your extension seems to be .c, that is correct for
a C-program. Check the Lint configuration.

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"Mal nommer les choses c'est ajouter du malheur au
monde." -- Albert Camus.
 
R

Robert Gamble

August said:
I used "nil pointer" to emphasize the distinction between the "points to
nothing" concept and the C macro constant NULL.

You said that literal 0 can denote the "nil pointer". There is no nil
pointer in C, but there is a NULL pointer constant which can be
expressed as a literal 0 in a pointer context. I don't see any
distinction in your statement, on the contrary it looks like you are
confused. In C, the NULL pointer "points to nothing", there is no
seperate concept of nil in C.
In Oberon for instance,
NIL is a keyword (typeless constant) used for pointers and variables of
procedure type.

This is C and there is no such thing.
-- August

Rob Gamble
 
K

Keith Thompson

Emmanuel Delahaye said:
That said, Lint seems to consider that '\0' is a char that is wrong in
C. (Or maybe, Lint is checking in C++ mode, in that case 0 is an int
and '\0' is a char). Your extension seems to be .c, that is correct
for a C-program. Check the Lint configuration.

I wouldn't say that Splint (the particular lint implementation that
generates the message) is wrong to issue a warning. It's not required
to limit itself to complaining about violations of the standard. It's
diagnosting (what its authors see as) a style issue -- which is part
of what lint is supposed to do. I happen to agree with it in this
case; initializing a char object with '\0' is clearer than using 0,
even though it's semantically identical.

test.c:6:4: Assignment of int to char: c = 0
Types are incompatible. (Use -type to inhibit warning)

In fact, types int and char are compatible for assignment (but not for
some other purposes). A naive programmer might infer from the message
that implicit conversions are a bad thing; this is a dangerous
assumption, since the obvious way to avoid them is to use casts, which
can be far more dangerous. And using the "-type" option would
probably inhibit some useful warnings.

A digression: In my opinion, C depends too heavily on implicit
conversions. If I were designing the language from scratch, most
conversions that are implicit in C would probably be explicit -- but
most of them would be expressed by some mechanism less heavyweight
than a cast. The resulting code would probably be more verbose than
typical C. If you like extreme terseness, be glad that I don't
actually design programming languages. But given the actual design of
C, it almost always makes sense to use implicit conversions rather
than explicit casts, which tend to swat flies with sledgehammers.
Implicit conversions are bad from a language design point of view, but
good (or at least far better than the alternative) from a C
programming point of view.
 
M

Malcolm

August Karlstrom said:
I used "nil pointer" to emphasize the distinction between the "points to
nothing" concept and the C macro constant NULL. In Oberon for instance,
NIL is a keyword (typeless constant) used for pointers and variables of
procedure type.
Conventionally C uses all bits zero to represent an invalid pointer. On a
few machines this isn't useful (maybe because of hardware traps or something
like that) so a different bit pattern will be used. The constant zero and
the definition NULL always represent this pointer, however.

There is no reason you cannot use other addresses to represent invalid
pointers internally, however. I cannot think of a good reason for so doing,
but it would be perfectly possible to set up a global somewhere and then
test against it before reading or writing. These would be nil pointers but
not null pointers.

(The situation isn't quite as simple as I have painted it because it is
illegal to do any sort of calculation with an invalid pointer, except a null
pointer. So strategies along the lines of
#define MYNULL 12345678
will work on some compliers but not all. The act of loading this address
into a rgister may trigger an error.).
 
K

Keith Thompson

Malcolm said:
Conventionally C uses all bits zero to represent an invalid pointer. On a
few machines this isn't useful (maybe because of hardware traps or something
like that) so a different bit pattern will be used. The constant zero and
the definition NULL always represent this pointer, however.

I would state this differently, to de-emphasize the idea that
all-bits-zero is "conventional".

C uses some specific pointer representation to represent a null
pointer. This is represented in source by a null pointer constant,
such as a literal 0 or the macro NULL. On many (most?)
implementations the internal representation happens to be
all-bits-zero, but well written C code does not know or care what the
actual representation is; it can even be different for different
pointer types.

(If you had written "typically" rather than "conventionally", I
wouldn't have had any quarrel.)
 

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
474,164
Messages
2,570,898
Members
47,439
Latest member
shasuze

Latest Threads

Top