need for an extra variable.

C

chandanlinster

hello everybody,
consider the following code snippet (from K & R, pg78)

while ((s[0] = c = getch()) == ' ' || c == '\t')
;

my question is, why would we need the variable 'c'.
We could easily write it as,

while ((s[0] = getch()) == ' ' || s[0] == '\t')
;
 
Z

Zero

chandanlinster said:
hello everybody,
consider the following code snippet (from K & R, pg78)

while ((s[0] = c = getch()) == ' ' || c == '\t')
;

my question is, why would we need the variable 'c'.
We could easily write it as,

while ((s[0] = getch()) == ' ' || s[0] == '\t')
;

I don't know the whole code,
but with the code above c gets also the value from getch()
and will be checked immediately with c=='\t'.
 
R

Richard Heathfield

chandanlinster said:
hello everybody,
consider the following code snippet (from K & R, pg78)

while ((s[0] = c = getch()) == ' ' || c == '\t')
;

my question is, why would we need the variable 'c'.
We could easily write it as,

while ((s[0] = getch()) == ' ' || s[0] == '\t')
;

c is used several times later in that function, and this includes the value
assigned to it here. Rewriting it without c could prove an interesting
exercise. I suggest you do so, testing your changes thoroughly. Then look
at the resulting code, and compare it to K&R's original. If you think your
replacement is clearer (and if it works identically), then feel free to use
it instead.
 
J

Jordan Abel

2006-11-01 said:
For extra credit, explain why this would be bad, at least in theory:

while ((s[0] = c = getch()) == '@')

(assume getch() is like getchar(), and that s is an array of char).

I give up, why?
 
A

Andrew Poelstra

2006-11-01 said:
For extra credit, explain why this would be bad, at least in theory:

while ((s[0] = c = getch()) == '@')

(assume getch() is like getchar(), and that s is an array of char).

I give up, why?

It might be that if EOF is inputted, any content found in stdin after
that is undefined. But I just made that up, so don't take it as true.
 
K

Keith Thompson

Jordan Abel said:
2006-11-01 said:
For extra credit, explain why this would be bad, at least in theory:

while ((s[0] = c = getch()) == '@')

(assume getch() is like getchar(), and that s is an array of char).

I give up, why?

getch() returns a result of type int. c is of type int. s[0] is of
type char. So this assigns a value of type int (which can be negative
if and only if it's equal to EOF) and assigns it to something of type
plain char; this involves an implicit conversion.

It's possible that EOF, after being converted from int to char,
happens to match the value of '@' (though not for any real-world
character set I'm aware of).

If plain char is signed, and the value returned by getch() exceeds
CHAR_MAX, there's the additional problem that the conversion from int
to char yields an implementation-defined result (or, for C99, may
raise an implementation-defined signal).
 
R

Richard Bos

For extra credit, explain why this would be bad, at least in theory:

while ((s[0] = c = getch()) == '@')

(assume getch() is like getchar(), and that s is an array of char).

5.2.1#3.

Richard
 
R

Richard Tobin

Keith Thompson said:
getch() returns a result of type int. c is of type int. s[0] is of
type char. So this assigns a value of type int (which can be negative
if and only if it's equal to EOF)

Where is this guaranteed? Characters in the basic execution set are
guaranteed to be non-negative when stored in chars (6.2.5), which implies
that they must be non-negative as ints, but other characters (such as
'@') have no such requirement as far as I can see.

Also, if char is unsigned, does anything stop EOF, when converted to
a char, matching the value of *any* character, even ' ' (which was
used in the original example)?

-- Richard
 
K

Keith Thompson

Keith Thompson said:
getch() returns a result of type int. c is of type int. s[0] is of
type char. So this assigns a value of type int (which can be negative
if and only if it's equal to EOF)

Where is this guaranteed? Characters in the basic execution set are
guaranteed to be non-negative when stored in chars (6.2.5), which implies
that they must be non-negative as ints, but other characters (such as
'@') have no such requirement as far as I can see.

Here's the code being discussed:

| while ((s[0] = c = getch()) == '@')
|
| (assume getch() is like getchar(), and that s is an array of char).

The value returned by getchar() (and therefore, by assumption, by
getch()) is either EOF (which is negative), or the next input
character *obtained as an unsigned char* and converted to an int. So
the value returned by getch() (and assigned to c) is negative if and
only if it's equal to EOF; even if '@' < 0, getch() will return a
positive value when '@' is the next character in the input stream.
Also, if char is unsigned, does anything stop EOF, when converted to
a char, matching the value of *any* character, even ' ' (which was
used in the original example)?

As I said in the previous article (and you didn't quote:

| It's possible that EOF, after being converted from int to char,
| happens to match the value of '@' (though not for any real-world
| character set I'm aware of).

More realistically, consider an implementation with 8-bit signed char
using an ISO 8859-1 (Latin 1) encoding, with EOF == -1. Character 255
is a lower case 'y' with an umlaut (two dots). If you read that
character using getchar(), the result is 255; if you then assign it to
a (signed) char, the assigned value is -1, which is EOF.
 
R

Richard Tobin

Keith Thompson said:
The value returned by getchar() (and therefore, by assumption, by
getch()) is either EOF (which is negative), or the next input
character *obtained as an unsigned char* and converted to an int.

Good point.
As I said in the previous article (and you didn't quote:
| It's possible that EOF, after being converted from int to char,
| happens to match the value of '@' (though not for any real-world
| character set I'm aware of).

Right. I chose '@' as being a character that I could type and could
be negative, since that way it could end up being -1 as a signed char.
You example of y-umlaut is more realistic. But if char is unsigned,
even characters guaranteed to be positive could match EOF as chars, if
EOF had a perverse value such as (int)0xffffff20. In which case the
original K&R code could fail.

-- Richard
 
J

Jordan Abel

2006-11-01 said:
2006-11-01 said:
For extra credit, explain why this would be bad, at least in theory:

while ((s[0] = c = getch()) == '@')

(assume getch() is like getchar(), and that s is an array of char).

I give up, why?

I figured it out. @ is not safe for source code interchange, you need \u0040.
 

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

Forum statistics

Threads
473,754
Messages
2,569,525
Members
44,997
Latest member
mileyka

Latest Threads

Top