Five different ways of incrementing a variable in C?
Started by 3 years ago●22 replies●latest reply 3 years ago●241 viewsHi there, sorry to bug you again, but I always learn useful stuff here -- again I'm writing a column -- and again I would appreciate the benefit of your feedback.
Question 1: Suppose we have a variable called Fred. As far as I'm aware, there are four ways we can increment this variable:
Fred = Fred +1;
Fred += 1;
Fred++;
++Fred;
Are you aware of any others (including any cunning tricks)?
Question 2: When it comes to the C operators, what are the most common misconceptions or errors in usage you've come across. For example, using:
Fred >> 1;
When you really mean to use:
Fred = Fred >> 1; or Fred >>= 1;
Thanks as always -- Max
It depends on definitions:
how about:
Fred -= -1;
Fred = increment(Fred);
not as different as your 4, but not the same.
I can't comment on frequency of confusion but one of the worst is thinking that:
(Fred >> 1) == (Fred / 2)
somtimes it will and sometimes it won't
MK
Ooh -- I like the "Fred -= -1;"
Re the (Fred >> 1) == (Fred / 2) -- is the "sometimes it won't" tied to the way different compilers treat signed integers -- will it always work for unsigned integers?
Using Fred -= -1; is not as unusual as you might think.
The AVR Compiler for ATMEGA chips almost always adds numbers by subtracting their -ve equivalent. Probably other compilers do too.
Why?
Oooh - good question - smarter minds than me write compilers!
Here's an example:
First the C code:
And the same line compiled:
Yes it will, there is an article on Stackoverflow about using right shift instead of divide.
The best advice is don't, let: the compiler decide when that optimisation is OK.
MK
Question 1: My suggestions (tested)
#include <stdio.h>
#include <stdint.h>
void main(void){
uint8_t fred = 40;
uint8_t i, o;
printf("Fred: %u\n", fred);
fred -= sizeof(fred)*255;
printf("Fred++: %u\n", fred);
// The hard way ...
(fred&1)?(fred&=~1,o=1,i=1):(fred|=1,o=0);
while(o&&i<sizeof(fred)*8)(fred&1<<i)?(fred&=~(1<<i),i++):(fred|=1<<i,o=0);
printf("Fred++++: %u\n", fred);
}
Hi, tcfkat!
You should enter the Obfuscated C Code Contest (https://www.ioccc.org/).
You have a really good chance to win!
:-)
I agree -- my eyes are still watering after reading TCFKAT's code
Oh, thanks!
But this is a simple bit-wise addition with a ripple-carry loop, nothing magic. Using digraphs and trigraphs, special variable names and removing all unnecessary whitespaces makes it more obfuscated:
??=include<stdio.h>
int main()<%unsigned _,__,___=41;printf("f:%u\n",___);(___&1)?(___&=??-1,__=1,_=1):(___??!=1,__=0);while(__&&_<sizeof(___)*8)(___&1<<_)?(___&=??-(1<<_),_++):(___??!=1<<_,__=0);printf("f++:%u\n",___);%>
If you are fired you should quickly change all code to this ... ;)
gcc -std=c11 -Wpedantic compiles without any warnings! ;)
Max, you asked for some cunning tricks to increment.
"If you are fired you should quickly change all code to this"
Interesting idea!!!
:-)
:-)
Afaik there are tools to do that. Or, are at least easy to write: removing all comments and whitespaces, rename all variables to cryptic random names, replace all by digraphs/trigraphs, etc.
But in times of revision control systems this is useless ...
@Max: sorry to go somewhat offtopic!
Hang on, you can say ++++ ?
Does that mean you could say:
--Fred++++;
But the prefix works different to the postfix -- so if I were to say:
Bert = --Fred++++;
I'd end up with Bert containing Fred + 2
However, () are at the highest precidence, so if I said
Bert = (--Fred++++);
Then I'd end up with Bert = Fred + 1 ... right?
The "++++" is only in the string, this is symbolic for two increments ... it is not a valid C syntax.
Ah -- my bad -- but then why doesn't the following work:
--Fred++;
Hi, MaxMaxfield!
I guess the '--' operator is intended to be used in very simple operations and this is not the case.
The compiler complaints that 'Fred++' is not an lvalue, but it would, after evaluation. Even '--(Fred++)' does not work!
Perhaps more skilled people here can have a better answer.
Cheers!
Thanks for the explanation!
Other thinking:
'Fred++' is an operation, hence, not an lvalue, even after executed.
It's starting to make sense :-)