I have some code that behaves differently between a Release build and a Debug build. It behaves correctly in Debug but not in Release.
I have a function that returns a ReadOnlyCollection<MyCustomClass>
. One section is this:
var result = new List<MyCustomClass>();
...
var list1 = this.returnEmptyList();
var list2 = this.returnListWithOneItem();
if (list1.Count == 0 && list2.Count == 0)
{
functionOutVariable = string.Empty;
return result.AsReadOnly();
}
For the purposes of troubleshooting I've simplified the code and named the variables in a generic fashion, and the methods returnEmptyList
and returnListWithOneItem
are shown here:
private List<string> returnEmptyList()
{
return new List<string>();
}
private List<string> returnListWithOneItem()
{
return new List<string> {"something"};
}
Clearly it should never enter the if
block because list2.Count
should always be 1, but when I execute this in a Release build, it does:
So there's clearly some optimization going on since you can see that list1
is inaccessible, and when stepping through it executed line 416 and then jumped immediately to line 421. I should state that all the assemblies in my solution use .NET Framework 4.6.2, and I'm running Visual Studio 2017 version 15.3.5.
When I change the build to Debug and execute this, it executes line 416, 417, and on line 418 it shows list1.Count
is 0 and list2.Count
is 1, and it correctly does not enter the if
block.
I'm trying to make a test project to reproduce this but I can't. I'm looking for any way to get to the bottom of this. I don't just want a fix that makes it go away - I need to understand what I'm doing wrong.
Release vs Debug and it depends on what language you are using, Debug includes debugging information in the compiled files (allowing easy debugging) while Release usually has optimizations enabled. They each define different symbols that can be checked in your program, but they are language-specific macros.
Debug Mode: In debug mode the application will be slow. Release Mode: In release mode the application will be faster. Debug Mode: In the debug mode code, which is under the debug, symbols will be executed. Release Mode: In release mode code, which is under the debug, symbols will not be executed.
Change the build configurationOn the toolbar, choose either Debug or Release from the Solution Configurations list. From the Build menu, select Configuration Manager, then select Debug or Release.
Ok, I'm pretty sure it's a result of a subtle bug in the rest of my function that allowed the compiler to just optimize out the if block and return early. I can reproduce the behavior of the debugger in this test project, and it totally makes sense in this case:
class Program
{
static void Main(string[] args)
{
var test = new MyClass();
test.DoTest(out var result);
Console.WriteLine(result);
Console.ReadKey();
}
}
class MyClass
{
public ReadOnlyCollection<MyCustomClass> DoTest(out string functionOutVariable)
{
var result = new List<MyCustomClass>();
var list1 = this.returnEmptyList();
var list2 = this.returnListWithOneItem();
if (list1.Count == 0 && list2.Count == 0)
{
functionOutVariable = string.Empty;
return result.AsReadOnly();
}
functionOutVariable = string.Empty;
return result.AsReadOnly();
}
private List<string> returnEmptyList()
{
return new List<string>();
}
private List<string> returnListWithOneItem()
{
return new List<string> { "something" };
}
}
class MyCustomClass
{
}
When I execute in a Release build with the debugger, it appears to enter the if
block, but in reality it just optimized out the if
block completely and the debugger confusingly shows it executing the lines inside the if
block instead of jumping over it:
Edit: I've confirmed there was a bug later in the function that was causing my problem, and the behavior of the debugger when looking at Release build code was just causing me confusion, due to compiler optimizations.
To be clear, my question is incorrect: the function was actually giving the same result in both Release and Debug builds but I was mistaken. That's because I followed this (flawed) sequence:
if
block incorrectly.if
block. I assumed (incorrectly) that was the source of my problem.
That sent me on the wild goose chase seen above. Sorry for wasting your time, but I certainly found the exercise informative. Perhaps someone else will learn from my mistake in the future. :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With