How do those other languages handle Siwastaja's earlier example of:
if( (retval = do_thing()) == -1)
simple: they don't allow for such vomit ! that is un-understandable. no wonder we have annual most obfuscated c code contests. this is extremely difficult to understand. syntax should be clear.
what is wrong with reformatting that to something readable ?
retval = dothing(); //statement begins with a variable so it is clearly an assignment.
if retval = -1 ... // statement begins with an if statement so it is a comparison.
there is no ambiguity when = means 'assign' or when it means 'compare' depending on the keyword , the parser descends one logic branch or another. if there is an 'if' keyword : descend down the compare branch , if there is a variable : descend down the assignment branch
that is simple and understandable.
Even then the point is still moot. Even with that convoluted source there is still no ambiguity : compiler knows we are evaluating an if statement hence a compairson that yields a boolean value ( if 1 then this, else that. ) an if statement is a pure boolean operation. It is a switch statement with only two possible paths.
So , the parser begins.
'if' |-> descend down comparison branch
'(' |-> recursive instantiate a new parser branch as we begin a new block
'retval' |-> variable this will be our first value
'=' |-> first statement was variable so = means assign descend down assign tree
'dothing()' // execute statement and collect return value
')' closing bracket. recursive instance terminates and passes 'retval' outward
outward parser now has 'retval' , which is a value
the parser now basically sees if(retval == -1) it has minimized away the retval = donothing() block to a variable. that bracketed block is done.
so , we are back into evaluating an if clause
left hand is 'retval'
= is a comparison clause (we are in an if block)
-1 is a constant
Look, the parser can figure out things much more complex than this ! Like that retval is a variable but dothing is a function call. You don't need to write things like :
if ((variable retval getsassignedresultof functioncall dothing(withnothingpassed) ) compareto constant -1) . Based on the syntax convention it knows what things are. So, based on the knowledge what things are it can also know when = means assign and when compare. like you cannot assign a value to a functioncall.
if (dothing() = -1) is the same as if(-1 = dothing())
like i said , many other languages , much older than C have no problems with this.
my gripe with it is that, as an infrequent coder , i often find that i make mistakes against this. and they can be very hard to find. You are inside an if clause, it is illogical to perform assignments in there )
if ((fruit= pick_a_fruit()) = apple)
why do you need that intermediate there ?
if (pick_a_fruit() = apple)
and, in case you really need to retain what was picked :
fruit = pick_a_fruit
if (fruit = apple)
i simply hate cryptical stuff. The simpler something is written the simpler it is to spot mistakes. And simpler does not mean 'less characters'. simpler means 'babytalk'. ditch complexity.
Hardcore c coders will state that this assign and compare contraction is 'elegant'. Which i read as : "if you don't understand it then you don't belong in our 'elite' club" snobbery
i've seen code where they do this kind of crap in for loops.... it takes you half an hour to figure out what the fuck they are doing. 'but it is elegant'. no it isn't . (and then on top of that they modify the loopcounter inside the block as well. that ought also be prohibited. use an exit clause to cleanly terminate the loop prematurely. it;s all about readability and maintainability)
Splitting it in multiple lines produces just as compact machine code. The end result is the same. it's just easier for humans to understand. and that is the part i like.