1

Today I was researching a bug which, in my opinion, was caused by an unnecessary mistake that a compiler could detect.

var isFoo = true;
var bar = 1;
if (isFoo = false && bar > 0) // Compiler is not warning about assignment instead of equality
{
// ...
}

It is not common for values to be set in a condition, so I would like to ask, is it possible to configure Visual Studio to throw warning or error in this case?

Muflix
  • 6,192
  • 17
  • 77
  • 153
  • 5
    You can use the so-called "Yoda Style" of coding: put the constant *first* in the test, like this: `if (false = isFoo && bar > 0)`. That will generate an error when you have `=` instead of `==`. Related: https://stackoverflow.com/q/2369226/10871073 – Adrian Mole Sep 07 '21 at 20:06
  • 1
    There's no mistake to detect. Assignment is an expression that returns the assigned value. `isFoo = false` actually returns false which means the expression becomes `(false && bar >0)` which is always false. This is used a *lot* in stream reader loops, eg `while(r=reader.Read() != -1){ ...}`. In the [StreamReader example](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamreader?view=net-5.0) `while ((line = sr.ReadLine()) != null)` is used to read lines in a loop – Panagiotis Kanavos Sep 07 '21 at 20:09
  • Thank you Adrian, I never heard of Yoda Style :-) – Muflix Sep 07 '21 at 20:26
  • Also note that the assignment operator has a lower priority than the `&&` operator, so `isFoo = false && bar > 0` will actually evaluate as `isFoo = (false && bar > 0)` – Klaus Gütter Sep 08 '21 at 05:13
  • `It is not common for values to be set in a condition,` that's incorrect. – Panagiotis Kanavos Sep 08 '21 at 08:52

3 Answers3

2

Most C/C++ compilers provide such a warning on a certain warnings level. Unfortunately, I wasn't able to find the same setting for the Visual Studio's C#/.NET compiler.

I think you may look into code analyzers which may provide the additional flexibility of forcing code rules that you need.

I haven't been using them myself yet, but I believe this is the right direction to move to.

  • There's no error to detect. Assignments are expressions that return the assigned value. The only problem in this case is that the expression is always false. – Panagiotis Kanavos Sep 07 '21 at 20:14
  • 1
    @PanagiotisKanavos I agree that there's no error, however it is a useful thing to have. And many C/C++ compilers, as I mentioned, provide such warnings if you desire to see them. It saved me a lot of time debugging such a mistake in my C project once. – TheNightdrivingAvenger Sep 07 '21 at 20:16
  • @PanagiotisKanavos There is nothing wrong -- I'm not doubting that. What I'm saying is that such mistakes may go unnoticed and bring you a lot of trouble if you're not careful enough. I believe this is what OP is asking. It's always better to see a warning/notice and discard it if you know what you're doing, than miss it completely. – TheNightdrivingAvenger Sep 07 '21 at 20:19
  • 1
    Thank you Night Driver! the `SonarAnalyzer.CSharp` is throwing following warning https://rules.sonarsource.com/csharp/RSPEC-2583 :-) – Muflix Sep 07 '21 at 20:25
  • @Muflix that warning doesn't complain about the assignment in the condition, it complains because the result is always false. – Panagiotis Kanavos Sep 08 '21 at 08:52
1

Use ReSharper. It will warn you that the expression is always true/false.

enter image description here

You might also get a compiler warning CS0162: Code is unreachable

eglease
  • 2,445
  • 11
  • 18
  • 28
-1

There's no mistake for the compiler to detect. Assignment is an expression that returns the assigned value. isFoo = false actually returns false which means the expression becomes (false && bar >0) which is always false. That's something that a code analyzer can detect: the expression is always false.

Using assignments as expressions is used very often in reader loops. In the StreamReader docs the example uses this to read text one line at a time:

using (StreamReader sr = new StreamReader("TestFile.txt"))
{
   string line;
   // Read and display lines from the file until the end of
   // the file is reached.
   while ((line = sr.ReadLine()) != null)
   {
       Console.WriteLine(line);
   }
}
Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236