DoNotCastUnnecessarily: Release vs Debug

When I compare the outputs of FxCop for my assemblies in Debug and Release build modes, the results are very different. The Debug report shows 233 more issues that are all related to "DoNotCastUnnecessarily" messages. Is the compiler optimizing things for a release build and that's why I don't see the messages in my Release report?
[341 byte] By [LeeGrissom] at [2008-2-14]
# 1
Sorta. The VB.NET compiler generates less garbage in "Release" builds, and the C# compiler has a few basic optimizations in that mode.

With some effort, you might be able to tell exactly what sort of actions are creating the difference you're seeing.

-Ryan / Kardax

RyanLamansky at 2007-9-9 > top of Msdn Tech,Visual Studio Team System,Visual Studio Code Analysis and Code Metrics...
# 2
This is certainly due to the IL that's generated by the compiler in debug v. release, but I'd need to see the IL to comment further on it. If you have two versions of a method handy for which a violation appears in Debug but not Release and want to send me the IL for each, I will take a look.

To get the IL, use ildasm, locate the method, double-click and copy the information into a mail message. You can do this in FxCop as well, load the assembly, analyze, find the method, select it in the target pane, right-click, select View IL. Copy the info in the resultant dialog.

You can send me the details for both versions at mikefan at microsoft dot com and I will let you know what's up.

Michael

MichaelFanning-MS at 2007-9-9 > top of Msdn Tech,Visual Studio Team System,Visual Studio Code Analysis and Code Metrics...
# 3
I was completely wrong in my previous message. For one thing, I note you're working in C#. Next, the issue here is simply that for your release build, you don't have pdbs available. That means that FxCop can't differentiate between a user- and compiler-provided variable. This basically shuts down analysis entirely for the DoNotCastUnnecessarilyRule (this rule filter out violations against compiler-emitted variables).

Possible solutions? 1) emit pdbs in your retail build, 2) analyze only your debug builds. Note that at Microsoft, teams typically choose a single build flavor for analysis. The build flavor is generally debug or (for teams that are very rigorous about testing the actual bits that ship) a special build flavor which is basically retail + CODE_ANALYSIS #defined on the cmd-line (in order to support in source suppressions). Note that in source suppressions are a Whidbey only feature.

public static BarSubItem FindMenu(BarManager manager, ActionMenu menu)
{
foreach(BarItem item in manager.Items)
{
ActionSubItem subItem = item
as ActionSubItem;
if (subItem != null && subItem.Menu == menu)
return (BarSubItem)subItem;
}
return null;
}

Above is the rewritten pattern of the code snippet you provided which will not fire an FxCop violation. Note that there's a single cast to subItem (using the as operator) and you subsequently test this result for null to insure the cast item was of the correct type.

Michael

MichaelFanning-MS at 2007-9-9 > top of Msdn Tech,Visual Studio Team System,Visual Studio Code Analysis and Code Metrics...
# 4
Very much appreciated Michael. I am a big proponent of using FxCop integrated with our Release build process, so I will talk with our build person to see about generating the pdb files so that we can get a more consistent and accurate listing of issues.
--
Lee
LeeGrissom at 2007-9-9 > top of Msdn Tech,Visual Studio Team System,Visual Studio Code Analysis and Code Metrics...
# 5
Michael Fanning - MS wrote:

Possible solutions? 1) emit pdbs in your retail build, 2) analyze only your debug builds. Note that at Microsoft, teams typically choose a single build flavor for analysis. The build flavor is generally debug or (for teams that are very rigorous about testing the actual bits that ship) a special build flavor which is basically retail + CODE_ANALYSIS #defined on the cmd-line (in order to support in source suppressions). Note that in source suppressions are a Whidbey only feature.

Bear with me. If I set the project configurations to emit the PDB (e.g. /debug command line option), are you saying that will affect the generated assembly as well? Something about "in source suppressions"? Can you elaborate on the CODE_ANALYSIS #defined topic a little more. How does that work?
--
Lee
LeeGrissom at 2007-9-9 > top of Msdn Tech,Visual Studio Team System,Visual Studio Code Analysis and Code Metrics...
# 6
Using the /debug+ or /debug:full options (these are exactly equivalent) will have some impact on your retail binary. In order to generate a pdb for retail builds, use the /debug:pdbonly option. Your generated binary should be identical. Note that the resultant pdb file has some limitations in terms of debugging, the most obvious difference being that you can't attach to a running program w/an assembly + pdb generated using /debug:pdbonly.

In v2.0 of the framework, system.dll ships with a new attribute, SuppressMessageAttribute, that can be used to suppress FxCop messages directly in source. This attribute information is only emitted if CODE_ANALYSIS has been #defined on the command-line. You would not want to ship binaries w/this in source suppression metadata, as it isn't relevant at runtime but has working set implications (the entire custom attribute metadata table is loaded into memory on any attempt to retrieve CA information from an assembly).

Michael

MichaelFanning-MS at 2007-9-9 > top of Msdn Tech,Visual Studio Team System,Visual Studio Code Analysis and Code Metrics...
# 7
Ah, there have been several questions about how to suppress FxCop messages for specifics parts of the code. Glad to hear it's available in Whidbey.
Slight problem: We're compiling the entire solution on the commandline rather than each individual project. But the /debug:pdbonly syntax is illegal for solutions. Is there a way to specify the /debug:pdbonly option by some other means? I tried to do it directly in the IDE, but there isn't any option. The "Generate Debugging Information" UI element in the Options dialog is just a boolean entry field. It doesn't allow for the ":pdbonly" suboption.
LeeGrissom at 2007-9-9 > top of Msdn Tech,Visual Studio Team System,Visual Studio Code Analysis and Code Metrics...
# 8
I found this interesting Blog:
http://blogs.msdn.com/jaybaz_ms/archive/2004/06/29/169024.aspx
It seems as if it might not be a security problem to generate the PDB files. It only adds 4KB to one of our assemblies. However, doing so, apparently disables the Optimization flag. So I'm faced with a tradeoff and a few more things to think about.
LeeGrissom at 2007-9-9 > top of Msdn Tech,Visual Studio Team System,Visual Studio Code Analysis and Code Metrics...
# 9
But wait a second, if you specify /debug:pdbonly does that disable optimizations in C#?

If not, you'd simply need to add this command-line argument explicitly to your build. This is certainly possible in C++, I will have to check if C# supports the same possibility.

Michael

MichaelFanning-MS at 2007-9-9 > top of Msdn Tech,Visual Studio Team System,Visual Studio Code Analysis and Code Metrics...
# 10
Michael Fanning - MS wrote:
But wait a second, if you specify /debug:pdbonly does that disable optimizations in C#?
Michael

That's what I'm hearing, but I haven't tried it. The problem is that we're not directly calling "csc.exe". We're calling "devenv.exe mysolution.sln", which in turn handles the rest of the work. There is no way to specify /debug:pdbonly in each of our projects via the IDE. It's only a boolean field of True or False. And apparently, there's a bug that disables optimizations even if you could enable the pdb. So, I've decided to run two build processes: First, we'll build our solution in Debug mode, run FxCop against that. Then we'll re-run our build in Release mode and continue with business as usual from there.
--
Lee
LeeGrissom at 2007-9-9 > top of Msdn Tech,Visual Studio Team System,Visual Studio Code Analysis and Code Metrics...
# 11
That's interesting (and worrying) that the optimizations are disabled if you enable the pdbs.

In all my 3 years of using .NET/Visual Studio .NET I never realized that. It's going to have to be something I look at when I get into work today and will probably mean that I will have to change the build process. ;)

This 'bug' (or feature) doesn't appear to be present in Whidbey. You can choose none, full or pdbonly. In fact, pdbonly is the default for the release build.

DavidM.Kean at 2007-9-9 > top of Msdn Tech,Visual Studio Team System,Visual Studio Code Analysis and Code Metrics...

Visual Studio Team System

Site Classified