Bug 10638 – Assignment can't be used as a condition

Status
RESOLVED
Resolution
WONTFIX
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-07-14T04:44:00Z
Last change time
2016-11-11T20:32:39Z
Keywords
spec
Assigned to
nobody
Creator
freeslave93

Comments

Comment #0 by freeslave93 — 2013-07-14T04:44:07Z
Suppose code void main() { int i = 0; if (i = 1) { //...... } } dmd compiler generates error: "assignment cannot be used as a condition, perhaps == was meant?" But next code passed successfully: void main() { if (int i = 1) { //...... } } It's a bit odd that assignment can not be used as condition while declaration can be. It works fine if we replace first code snippet with this: void main() { int i = 0; if (cast(bool)(i = 1)) { //...... } } I guess assignment has no implicit cast to bool, it's weird too. If it's not error, please, explain me the reasons of this restriction. Also dlang.org defines ifStatement as "if ( IfCondition ) ThenStatement", where ifCondition can be Expression (hence AssignExpression too), but it seems it does not work at practice.
Comment #1 by mailnew4ster — 2013-07-14T04:48:30Z
I believe the primary reason is to prevent bugs where == was meant and not =. Usually, what you want to do is: void main() { int i = f(); if (i == 1) { //...... } }
Comment #2 by bearophile_hugs — 2013-07-14T04:58:13Z
(In reply to comment #1) > I believe the primary reason is to prevent bugs where == was meant and not =. > Usually, what you want to do is: > > void main() > { > int i = f(); > if (i == 1) > { > //...... > } > } Right. D is working as designed here, it helps avoid bugs. > Also dlang.org defines ifStatement as "if ( IfCondition ) ThenStatement", > where ifCondition can be Expression (hence AssignExpression too), > but it seems it does not work at practice. Then maybe that's what needs fixing.
Comment #3 by kevin — 2016-11-11T20:32:39Z
D has a number of language features (restrictions?) that are designed to make buggy code less likely to happen. A missing equals sign in a comparison is one of those common bugs. To get around it, you need to be explicit with your intent. An "if statement" is a poor example to use because you can always place the assignment before the comparison, but take for example a while loop: while(line = file.readln()) { ... } Since readln will return a null string when you reach the end of file input, the loop will terminate. However, you can't assign in a comparison, so what to do? One option is to be explicit in your intent by using a compound statement. while(line = names.readln(), line) { ... } A better option is to be explicit in your comparison as well, using this example from the documentation: while ((line = stdin.readln()) !is null) { ... } The example that you give isn't the best, since your assignment always evaluates to true, but perhaps you would prefer these examples: if (i = getValue(), i) { ... } if ((i = getValue()) == 1) { ... }