Why does the value get discarded in this case?

C

Chad

When I have:

int main(void)
{
int x = 256;
x>>8;

printf("The value is: %d\n", x);
return 0;
}

I get:

[cdalten@localhost ~]$ gcc -g -Wall seq.c -o seq
seq.c: In function 'main':
seq.c:6: warning: statement with no effect
[cdalten@localhost ~]$ ./seq
The value is: 256


However, when I change x from x>>8 to x++

#include <stdio.h>

int main(void)
{
int x = 256;
x++;

printf("The value is: %d\n", x);
return 0;
}

I get:

[cdalten@localhost ~]$ gcc -g -Wall seq.c -o seq
[cdalten@localhost ~]$ ./seq
The value is: 257

The question is, how come something like x>>8 discards the value right
away, but x++ doesn't?
 
R

Richard Heathfield

Chad said:

The question is, how come something like x>>8 discards the value right
away, but x++ doesn't?

It does. The difference is that x++ has a side-effect, which x>>8
doesn't, and the compiler considers it plausible that you wrote x++ not
for its value but for its side-effect, so it doesn't produce a
diagnostic message in the x++ case.
 
R

Richard Tobin

Chad said:
The question is, how come something like x>>8 discards the value right
away, but x++ doesn't?

x>>8 is just like x+1 or x/2 - it doesn't change the value of x.
It gives you the value of 8, shifted right 8 places. It doesn't
shift x itself.

x>>=8 does what I think you are expecting.

-- Richard
 
C

Chris Dollin

Chad wrote:

int main(void)
{
int x = 256;
x>>8;

printf("The value is: %d\n", x);
return 0;
}

I get:

[cdalten@localhost ~]$ gcc -g -Wall seq.c -o seq
seq.c: In function 'main':
seq.c:6: warning: statement with no effect

The shift operation `x >> 8` takes the value of `x`,
shifts it 8 places to the right, and throws the
result away.
int main(void)
{
int x = 256;
x++;

printf("The value is: %d\n", x);
return 0;
}

The post-increment operation `x++` delivers (and discards)
the original value of `x`, and also arranges that `x`
is incremented.
The question is, how come something like x>>8 discards the value right
away, but x++ doesn't?

`x++` /does/ discard its value right away, the same as `x>>8` does.
However, the /increment operation/ is a side-effect, not a value,
and happens regardless.
 
R

Richard Tobin

Chad said:
What's the rationale behind having something like x>>8 not having a
side-effect, but somthing like, x++ having a side effect?

Why do you think that x>>8 should be like x++? Is it because of
the repeated >? In fact >> is like +, -, *, and /, none of which
have side effects.

-- Richard
 
C

Chad

What's the rationale behind having something like x>>8 not having a
side-effect, but somthing like, x++ having a side effect?
 
C

Chris Dollin

Chad said:
What's the rationale behind having something like x>>8 not having a
side-effect, but somthing like, x++ having a side effect?

`x >> 8` is like `x + 1`. It has no side-effect because if it did,
expressions would be updating their operands all over the place.
Ikk.

`x++` has a side-effect because that's what it's /for/; to provide
the value of a variable and to update it, to make common combinations
of operations more compact (and maybe, in the old days, more efficient).

An expression like `a[i++]` allows you to get at an element of an
array /and/ advance the index to the next position, all in one go.
Otherwise you'd have to find somewhere to put the increment, `i += 1`.

Opinions on whether this kind of elegant compactness is a good idea
are rumoured to vary. As with most programming languages features,
it's possible to overdo things, and it's possible to misunderstand
what such expressions actually /mean/ and where the language crouches
ready to pull the rug out from under your feet, giggling like an
insane ferret on nitrous oxide.
 
K

Keith Thompson

Chris Dollin said:
Chad said:
int main(void)
{
int x = 256;
x>>8;

printf("The value is: %d\n", x);
return 0;
}

I get:

[cdalten@localhost ~]$ gcc -g -Wall seq.c -o seq
seq.c: In function 'main':
seq.c:6: warning: statement with no effect

The shift operation `x >> 8` takes the value of `x`,
shifts it 8 places to the right, and throws the
result away.
[...]

Um, that's not quite the way I'd put it.

The expression x>>8 yields the value of x right-shifted by 8 bits.
Throwing away the result isn't a feature of the ">>" operator; the
result is thrown away because you (the OP) asked for it to be thrown
away, by using the expression as a statement (by adding the ';').

What x>>8 *doesn't* do is modify the value of x, just as the
equivalent x/256 doesn't modify the value of x. Similarly, 256>>8
doesn't modify the value of 256, and 2+3 doesn't modify the value of 2
or 3.

The ++ operator, as numerous others have pointed out, has the *side
effect* of modifying the object that is its operand. That's why the
++ operator, unlike the >> operator, can *only* be applied to an
object (an lvalue); 256++ is illegal.

If you *want* to modify the value of x, replacing it with the result
of x>>8, you can write:

x = x>>8;

or, equivalently:

x >>= 8;

A couple of notes on the original program:

You're missing the "#include <stdio.h>". Your program may happen to
appear to work without it, but it's mandatory if you use printf or
anything else declared in <stdio.h>. (Somebody might point out that
you could drop the #include and declare the printf function yourself;
that's true, but it's a dumb thing to do.)

You can use bitwise operators, (<<, >>, &, |, ^) on signed integers if
you really want to, but it almost always makes much more sense to
apply them to unsigned integers. There are rules on how these
operators work on negative values, but I can't be bothered to look
them up.
 
C

Chad

Why do you think that x>>8 should be like x++? Is it because of
the repeated >? In fact >> is like +, -, *, and /, none of which
have side effects.

-- Richard

Today, somewhere between me considering if I should make a third
attempt to apply to UC-Berkeley and my manager at work asking me if I
was dumb, the whole x>>8 vs x++ sank in. Then as the accounting lady
at work was making more sexual advances at me, I realized I could have
saved myself posting on here had I given the whole x>>8 vs x++ more
than a millisecond of thought before giving up.
 
C

Chris Dollin

What a charming image - may I reuse it, please?

Certainly. No attribution required (but appreciated if present).

--
"It was the first really clever thing the King had said that day."
/Alice in Wonderland/

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

Chris Dollin

Keith said:
Chris Dollin said:
Chad said:
int main(void)
{
int x = 256;
x>>8;

printf("The value is: %d\n", x);
return 0;
}

I get:

[cdalten@localhost ~]$ gcc -g -Wall seq.c -o seq
seq.c: In function 'main':
seq.c:6: warning: statement with no effect

The shift operation `x >> 8` takes the value of `x`,
shifts it 8 places to the right, and throws the
result away.
[...]

Um, that's not quite the way I'd put it.

The expression x>>8 yields the value of x right-shifted by 8 bits.
Throwing away the result isn't a feature of the ">>" operator; the
result is thrown away because you (the OP) asked for it to be thrown
away, by using the expression as a statement (by adding the ';').

Ooof. You're quite right, Keith; I was sloppy. Thanks for the catch.
 

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,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top