Even though the OP sepcifically asks for different syntax to prevent this kind of error, I would make the case that a better approach is a semantic solution:
The reason why this error can occur in C++ (and in C for that matter) is that an assignment expression evaluates to a reference to the assigned variable (int&
in this case) and that int
is implicitly convertible to bool
(*). By changing either of these properties we can prevent this error.
If we forbid implicit narrowing conversions or just the implicit int -> bool
conversion we are already fine. This however prevents the following common C idiom:
int status = my_api_call(/* ... */);
if (status) { /* Handle error */ }
But I would argue that this alternative code is easier to understand and just as simple to write:
int status = my_api_call(/* ... */);
if (status != 0) { /* Handle error */ }
If we evaluate assignment expressions not to a reference to the assigned value but to void
we also solve the problem, but this time we prevent this idiom:
a = b = c; // Assign the value of c to a and b
However this is rarely used and confusing if not seen before, and the alternative
a = c;
b = c;
is not significantly more verbose (and much clearer), so I would argue that losing this idiom is also not much of a loss if not an improvement.
So in conclusion I argue that while either of the approaches solves the problem, both of them are reasonable in their on right and can prevent other possible code smells.
Also now you are free to choose whatever syntax you like without the restriction of having to solve this problem.
(*) On top of that, in clauses of if
statements, also explicit conversions to bool
are considered in C++. This rule exists so class authors can make conversions to bool
explicit, which prevents implicit conversions from the custom type to integral types (via class X
-> bool
-> int
) while still allowing the class to be used as a condition in if
statements, but in our case it makes matters worse.
nuclear_code = 1234;
can be a statement withoutnuclear_code = 1234
needing to be allowed as an expression; Python did this before eventually relenting and adding the assignment operator:=
. Another issue that works against C in this regard is the coercion to boolean; in Java,if(nuclear_code = 1234)
would be a type error because the condition must be aboolean
, not anint
. $\endgroup$=
for both things because the context determines whether it's a name binding or an equality check. $\endgroup$