There are zero reasons to use that ugly and unnatural Yoda notation in 2019.
There are zero reasons to use that ugly and unnatural Yoda notation in 2019.
if (systemcall(“some string”, expression_argument(args), SC_MODE_1 | SC_MODE_DEFAULT) != 0)
if (0 != systemcall(“some string”, expression_argument(args), SC_MODE_1 | SC_MODE_DEFAULT))
One may find it easier to read/navigate flow control in C code that returns status codes, when these codes are stated beforehand. When there are series of long lines and a mix of 0==success and 0==false, it is easy to get lost, at least in my experience. int result = systemcall(“some string”, expression_argument(args), SC_MODE_1 | SC_MODE_DEFAULT))
if (result != 0)
Separation of concerns. Each line does one thing. Making a system call and branching on its result are two separate tasks.Did you compare writing in different ways and reading it later? This specific style confuses me the most, because I have to mentally connect an assignment with a flow control, because there is no guarantee that a following if() will not use a different variable or it was not shadowed, misnamed, etc. And given that, at once I see x2-3 lines less than usual.
In the past, I've done things like this:
#define TRY(exp) \
do { \
int TRY_result = exp; \
if (TRY_result != 0) \
return TRY_result; \
} while (0)
And then instead of the above I can just write: TRY(systemcall(“some string”, expression_argument(args), SC_MODE_1 | SC_MODE_DEFAULT)));
(Sometimes, one wants more complex error detection than just comparison to zero, or more complex error handling than just returning the result code. Often, it is possible to build a more complex version of the above TRY macro to meet those specific requirements.)"Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems."
while ((status = systemcall(...)) != SUCCESS) {
do something with status;
}
Leave a comment there explaining the assignment.Likewise:
if ((status = systemcall(...)) != SUCCESS) goto error;
Or something like that. I don't understand the hate, just make sure it's obvious what you're doing. while(status != SUCCESS) {
status = syscall(...);
// do something with status
} while (1) {
int ret = ...;
if (ret == ...) break;
if (ret == some_other_condition) break;
// additional termination conditions....
// do exactly one thing
} int c;
while((c = getopt(argc, argv, argstr)) >= 0) {...}
I’d say it’s acceptable, and Python is adding syntax so it can mix assignments and checks.But enabling it on the language level brings a large amount of risk and complexity just for what amounts to a micro-optimization.
Please don't. This is a perfectly understandable idiom in C. Don't explain the language in your comments; that's the job of a text book, which should be read by anyone before they read your code.
It also reduces time in debugging as you catch it immediately.
It's my favourite way of writing if statements.
Specifically, it's both (1) easy to make a typo where you meant "==" but typed "=" and (2) not easy to visually distinguish the two.
Java for example expects a bool for for if(). if(a=b) is only valid when they are, which is relatively rare. So it is mostly a compile error.
If C didn't allow assignments to be used as expressions, then it wouldn't be an issue.
Chained assignment isn't the only way to use an assignment within an expression, so I think it's still more accurate not to say chained assignment as the cause, but chained assignment might have been a big part of the motion for making assignments expressions instead of just statements.