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) { ... }