17 ms·
And this is why you write it like this when you use C: (0 == current->uid) Rather than (current->uid == 0) // or (current->uid = 0) in this case. Impo
by harrytuttle 13y ago
And this is why you write it like this when you use C:
(0 == current->uid)
Rather than
(current->uid == 0) // or (current->uid = 0) in this case.
Impossible to make an assignment to a numeric lvalue. Easy to spot, easy to audit in a diff.
- Fuxy 13y agoGood point i always wondered why people write it like that it makes it harder to read.
- mikevm 13y agoMakes one appreciate languages like Pascal which differentiate between the equality operator '=' and the assignment operator ':='. I wonder why the decision was made in C to use '=' and '=='? I'm betting it has something to do with the laziness of the programmers :).
- dchest 13y agoThe problem is not in == vs =, it's in allowing assignment as an expression. Go fixes this, for example, by now allowing them: if a = 0 {} gives compile error.
- deleted 13y ago[deleted]
- Grue3 13y agoThe problem is that == and = look similar. Banning assignment as expression only makes the language less expressive. Common Lisp fixes this, by having assignment and comparison look completely different: (setf variable value) vs (eql variable value)
- jimmaswell 13y agoBit of a bummer, I often find using assignment as an expression useful, like if (x = y as String) == null or such in c#. I get the feeling Go sacrifices a bit too much freedom.
- benjamincburns 13y agoOr you could also blame it on not having branch statements which enforce the use of a boolean type. Edit: Actually, forget I said this. It's a dumb statement. 'if(a = true)' would always pass, regardless of the value of 'a'.
- sigkill 13y agoI'm not a professional programmer by any stretch, but wouldn't this problem completely go away if the C and C++ compilers detect a single = inside an if statement and outright refuse it. Either that or automatically substitute the assignment with checking for instances inside the if-condition. The reason I'm asking is, because I don't know if there's ever a case where you'd want to assign right inside the if-condition. Is there?
- comex 13y agoThere can be: if (Foo *foo = getFoo()) { // getFoo returns null if there is no foo // There is a foo } However, this problem is basically entirely addressed by compiler warnings, which generally ask you to add an extra set of parens for this case.
- James_Duval 13y agoThanks for this. I don't actually use C, although I know a few languages with C-like syntax (Java, JS, AS2.0) and I'm learning Go & planning to learn D. This small change will be really helpful in all these languages. Even if I never make this error again it will help stop people who alter my code from making this error. Perhaps they should teach it in more programming textbooks, as I've not come across it in anything from HeadFirst to online tutorials to Deitel & Deitel.
- zwp 13y agoFYI, sometimes called "Yoda condition". I _think_ I was taught to do this when I learnt C (~20 years ago). Wikipedia indicates that the name at least has been around since 2005.
- hyperpape 13y agoIt's not necessary in Java (though it's still a common habit). Assignment to a non-boolean is impossible in an if statement in Java, and you can make the compiler warn you about accidental assignments.
- rbanffy 13y agoStill, assigning a boolean rather than comparing it is still possible and, possibly, a source of bugs.
- eksith 13y agoThis is the same procedure (or rather should be) in PHP. Also, better to switch to === or !== for exact comparisons since that also checks type. (I'll leave out the other warts of PHP since that's been discussed here and elsewhere ad nauseum)
- bello 13y agoPlease don't do that...
- deleted 13y ago[deleted]
- ndr 13y agoThat what? Why not?
- bello 13y agoWriting (0 == a) instead of (a == 0) to check a's equality with 0. It sacrifices readability. I'm sure there are tools (if not one can easily write one) that warn you for accidental assignment when comparison was meant instead. Moreover, the (0 == a) trick only works for constants (which you can't assign values to, hence the compiler will complain), but not for variables. I.e. you can still do if (a = b) accidentally, when comparison was intended.
- bello 13y agoPlease don't do that...
- bello 13y agoPlease don't do that...
- konst13 13y agoYou don't do that because it makes the code less readable. If you codebase is really big you have to read the code all the time and it takes more brain power to translate your version. Also gcc has a warning vor assignments in if, which are imho a bad habit.
- huhtenberg 13y ago> And this is why you write it like this when you use C: Sure, if you are in habit of releasing code that compiles with warnings. This sort of pointless code twisting is intensely annoying. It solves a rare problem with a wrong tool and in a very intrusive way. Zero is constant. You compare to it.
- harrytuttle 13y agoHuh? $ cat test.c int main(int argc, char *argv[]) { if (0 == argc) return 1; return 0; } $ CFLAGS="-Wall -ansi -pedantic" make test cc -Wall -ansi -pedantic test.c -o test Nope, no warnings there.
- imancit 13y agoRight, but if you compile with warnings as errors, then assignment within a condition won't compile, which prevents the issue. I'd much rather go that way than write code that reads less like a human wrote it.
- harrytuttle 13y agoWhat compiler flag is that? Genuinely interested. Wall,pedantic,ansi don't trigger it. I've tried the following and I don't get a warning or error: $ cat test2.c int main(int argc, char *argv[]) { if (argc = 0) return 1; return 0; } $ make test cc -Wall -ansi -pedantic test.c -o test GCC version: gcc version 4.7.2 (Debian 4.7.2-5)
- huhtenberg 13y agohuh@px:/tmp$ cat a.c int main(int argc, char *argv[]) { if (argc = 0) return 1; return 0; } huh@px:/tmp$ gcc -Wall a.c a.c: In function 'main': a.c:2: warning: suggest parentheses around assignment used as truth value
- 13y ago
- colanderman 13y agoOr run a linter or static checker which disallows assignments in conditionals as part of your build and/or checkin process. They'll catch this and other fun C "gotchas" without relying on human vigilance.
- harrytuttle 13y agoThat's the failsafe (one I believe heavily in as well). But getting it right up front is still the best approach.
- liopleurodon 13y agoI see what you're saying, but (0 == current->uid) still makes my eyes bleed
- harrytuttle 13y agoI agree with you, but it works and it's saved me hours and hours of crying in front of gdb.