Bitwise Operator no change the value

WBahn

Joined Mar 31, 2012
29,978
why my variable has not changed after I apply the right shift operator?

int a = 0b0111;
a >> 1;
printf("%d", a);
For the same reason that having the statement

a + 10;

won't change the value of a.

All you have done is evaluated an expression and then thrown away the result without doing anything with it.
 

ApacheKid

Joined Jan 12, 2015
1,533
why my variable has not changed after I apply the right shift operator?

int a = 0b0111;
a >> 1;
printf("%d", a);
Ha, good old 'C' again, it's inexcusable that such code compiles and can be executed! A statement which is just an expression is one of the reasons C's semantics leads to so many problems in the real world. Your code is incorrect but legal, and I can understand why you'd reasonably expect that statement to have some effect on the output.
 

Papabravo

Joined Feb 24, 2006
21,159
Ha, good old 'C' again, it's inexcusable that such code compiles and can be executed! A statement which is just an expression is one of the reasons C's semantics leads to so many problems in the real world. Your code is incorrect but legal, and I can understand why you'd reasonably expect that statement to have some effect on the output.
That is a specious argument. It is most assuredly not incorrect, but it produces a result the may not have been expected. Nowhere is it written that a program has to produce an observable result. Doing nothing is a time honored programming construct.
 

ApacheKid

Joined Jan 12, 2015
1,533
That is a specious argument. It is most assuredly not incorrect, but it produces a result the may not have been expected. Nowhere is it written that a program has to produce an observable result. Doing nothing is a time honored programming construct.
Well I certainly would expect the result that we get because I know of C's many oddities. The OP though did not and that's partly because it's very rational to expect a statement to cause some kind of state change or at least potential state change.

The reason C allows statements that are simply expressions is because the language allows functions to be invoked by the mere presence of their name and so a function is just a kind of expression and so expressions too can just appear as statements.

After all

Code:
a++;
b--;
do cause a state change as you well know.

Perhaps they should have allowed:

Code:
a >>>> 1;
To mean:

Code:
a = a >> 1;
at least there'd be some consistency...
 

WBahn

Joined Mar 31, 2012
29,978
Ha, good old 'C' again, it's inexcusable that such code compiles and can be executed! A statement which is just an expression is one of the reasons C's semantics leads to so many problems in the real world. Your code is incorrect but legal, and I can understand why you'd reasonably expect that statement to have some effect on the output.
Yes, we all know that you hate C. Constantly griping about it in every thread where someone asks a question about C does not help anyone. Your complaining about it does not change it. The person still has to understand the language whether you like the language or not.
 

WBahn

Joined Mar 31, 2012
29,978
Well I certainly would expect the result that we get because I know of C's many oddities. The OP though did not and that's partly because it's very rational to expect a statement to cause some kind of state change or at least potential state change.
Really?

So what kind of state change should be rationally expected by

a + b;
The reason C allows statements that are simply expressions is because the language allows functions to be invoked by the mere presence of their name and so a function is just a kind of expression and so expressions too can just appear as statements.
Not true. The mere presence of a function's name does NOT invoke the function. It is an expression that evaluates to a pointer to the function. You need to dereference the name with the function call operator, which is a pair of parens that can optionally contain a list of arguments to the function.

But, aside from that, what do you base this claim on? How do you know it isn't the other way around and that functions can be dereferenced and invoked as an expression because the languages does not require expressions to have side effects?

After all

Code:
a++;
b--;
do cause a state change as you well know.
So? That's because these are operators that have side effects.

a = b;

is an operator that causes a state change, too, because = is also an operator that has side effects.

Perhaps they should have allowed:

Code:
a >>>> 1;
To mean:

Code:
a = a >> 1;
at least there'd be some consistency...
Huh??? How is that consistent? Consistent with what?


a >>>> 1;

is not consistent with ANYTHING! After all, we don't write

a++1;

Notice that a++ is a UNARY operator (that happens to also have a side effect).

a >>>> 1;

would be a BINARY operator.

The equivalent that you are looking for is

a = a + 1;

and

a += 1;

But, hey, guess what?

a = a >> 1;

is the same as

a >>= 1;

just like any other binary operator can be written as an abbreviated operator.

So there IS consistency.
 
Last edited:

ApacheKid

Joined Jan 12, 2015
1,533
Yes, we all know that you hate C. Constantly griping about it in every thread where someone asks a question about C does not help anyone. Your complaining about it does not change it. The person still has to understand the language whether you like the language or not.
I beg your pardon? The OP is apparently very unfamiliar with C and is unlikely to find its shortcomings celebrated in any book he might be using. Having an awareness of the pitfalls and potential traps that one's tools might possess is a valuable trait in any engineer.

I'm critiquing C you are critiquing me, so lets avoid making personal attacks please.
 

ApacheKid

Joined Jan 12, 2015
1,533
Really?

So what kind of state change should be rationally expected by

a + b;


Not true. The mere presence of a function's name does NOT invoke the function. It is an expression that evaluates to a pointer to the function. You need to dereference the name with the function call operator, which is a pair of parens that can optionally contain a list of arguments to the function.

But, aside from that, what do you base this claim on? How do you know it isn't the other way around and that functions can be dereferenced and invoked as an expression because the languages does not require expressions to have side effects?



So? That's because these are operators that have side effects.

a = b;

is an operator that causes a state change, too, because = is also an operator that has side effects.



Huh??? How is that consistent? Consistent with what?


a >>>> 1;

is not consistent with ANYTHING! After all, we don't write

a++1;

Notice that a++ is a UNARY operator (that happens to also have a side effect).

a >>>> 1;

would be a BINARY operator.

The equivalent that you are looking for is

a = a + 1;

and

a += 1;

But, hey, guess what?

a = a >> 1;

is the same as

a >>= 1;

just like any other binary operator can be written as an abbreviated operator.

So there IS consistency.
Yes you are right, the name alone does not lead to invocation we need the argument list. Yes you are right

Code:
a >>>> 1;
was not a correct analogy, but

Code:
a >>>>;
is.

When learning to reason about source code, especially other people's or poorly expressed source code, the characteristics of C's semantics are important. I think it's extremely important that the newcomer be aware of all of these idiosyncratic language behaviors if one is to master the language.

A hallmark of well designed languages is they are easier to reason about than C, they are more intuitive than C, this is not a "gripe" it is an engineering truism, a fact backed up by solid evidence and I make no apologies for bringing this kind of thing to the OP's attention.
 

WBahn

Joined Mar 31, 2012
29,978
Yes you are right, the name alone does not lead to invocation we need the argument list. Yes you are right

Code:
a >>>> 1;
was not a correct analogy, but

Code:
a >>>>;
is.
I don't see how this is a correct analogy at all.

a >> 1

is a binary operator. The right hand operand does not HAVE to be 1, it just HAPPENS to be 1 in THIS example.

For your analogy to work, you have to maintain that ANY expression of the form

a = a op 1;

must be able to be written as

aopop;

Thus

a = a & 1;

must be able to be written as

a&&;

in order for the language to be "consistent".

For most binary operators, abbreviated assignment forms are legal. So that

a = a op b;

can be expressed as

a op= b

That's pretty darn consistent.

Now, it is true that abbreviated assignment operators are not supported for ALL binary operations. For instance, they are not provided for relational operators. But this make sense, since

a = a < b;

while legal, doesn't really make conceptual sense. On the right hand side, a and b are arithmetic types, but the result of the expression is a Boolean type.

So is it a true statement that abbreviated assignment operators are provided for all binary operations in which the result is the same (conceptual) type as the left operand?

Let's see.

Arithmetic operators: {+, -, *, /, %} YES
Relational operators: {==. !=, >, >=, <. <=} NO -- but the operand is arithmetic while the result is Boolean.
Logical operators: {&&, ||} NO -- but the operand can be arithmetic, while the result is Boolean. This is a somewhat weak claim.
Bitwise: {&, |, ^, <<. >>} YES
Structure operators: {->, .} NO -- but the operand is a structure or structure pointer, while the result can be just about anything.
Comma operator: {,} NO -- but the result is the type of the right operand, which is independent of the type of the left operand.

I think that's all of them.

So with the arguable exception of the two logical operators, there is strong consistency in the availability of an abbreviated assignment operator for compatible binary operators.

It seems that a reasonable question/criticism is why

a = a && b;

can't be written as

a &&= b;

I can see this being relevant and useful in any number of applications.

I've also always been annoyed by the lack of a logical-XOR, ^^, for symmetry with the set of bitwise operators. I have had MANY occasions in which that would be been useful.

The increment and decrement operators are special operators provided for a specific purpose, namely to allow a simple compiler running on a 1970-era computer to be able to leverage the increment and decrement instructions commonly found on many processors. The instructions intrinsically combine a specific operation with a specific side effect, so it's not surprising that the language constructs that invoke them intrinsically combine that same specific operation with that same specific side effect.
 

ApacheKid

Joined Jan 12, 2015
1,533
I don't see how this is a correct analogy at all.

a >> 1

is a binary operator. The right hand operand does not HAVE to be 1, it just HAPPENS to be 1 in THIS example.

For your analogy to work, you have to maintain that ANY expression of the form

a = a op 1;

must be able to be written as

aopop;

Thus

a = a & 1;

must be able to be written as

a&&;

in order for the language to be "consistent".

For most binary operators, abbreviated assignment forms are legal. So that

a = a op b;

can be expressed as

a op= b

That's pretty darn consistent.

Now, it is true that abbreviated assignment operators are not supported for ALL binary operations. For instance, they are not provided for relational operators. But this make sense, since

a = a < b;

while legal, doesn't really make conceptual sense. On the right hand side, a and b are arithmetic types, but the result of the expression is a Boolean type.

So is it a true statement that abbreviated assignment operators are provided for all binary operations in which the result is the same (conceptual) type as the left operand?

Let's see.

Arithmetic operators: {+, -, *, /, %} YES
Relational operators: {==. !=, >, >=, <. <=} NO -- but the operand is arithmetic while the result is Boolean.
Logical operators: {&&, ||} NO -- but the operand can be arithmetic, while the result is Boolean. This is a somewhat weak claim.
Bitwise: {&, |, ^, <<. >>} YES
Structure operators: {->, .} NO -- but the operand is a structure or structure pointer, while the result can be just about anything.
Comma operator: {,} NO -- but the result is the type of the right operand, which is independent of the type of the left operand.

I think that's all of them.

So with the arguable exception of the two logical operators, there is strong consistency in the availability of an abbreviated assignment operator for compatible binary operators.

It seems that a reasonable question/criticism is why

a = a && b;

can't be written as

a &&= b;

I can see this being relevant and useful in any number of applications.

I've also always been annoyed by the lack of a logical-XOR, ^^, for symmetry with the set of bitwise operators. I have had MANY occasions in which that would be been useful.

The increment and decrement operators are special operators provided for a specific purpose, namely to allow a simple compiler running on a 1970-era computer to be able to leverage the increment and decrement instructions commonly found on many processors. The instructions intrinsically combine a specific operation with a specific side effect, so it's not surprising that the language constructs that invoke them intrinsically combine that same specific operation with that same specific side effect.
I will be the first to agree, admit there are understandable reasons, justifications for the decisions the designers made way back when C was embryonic. No doubt many of these were compromises and for the sake of expediency, after all the main motivation for C was to enable Unix to be developed, at the time there was no easy to implement language they could use (yes PL/I was a possibility but as the Multics history shows that was a large undertaking at the time, one could not just get or buy a PL/I compiler).

I'm attempting to address the shortcomings we see in C and attempting to leverage PL/I as the basis for an improved systems language that is not C or PL/I, but that's another story so I won't say any more here.
 
Top