我们有一个使用StyleCop和代码分析来验证代码结构的项目。我们已经将“处理警告”设置为两种机制的错误。
然而,我们发现了一种我们无法解释的不良行为。我们有一个调试和发布配置。在我们的调试配置中,我们没有得到一个CA警告,而我们在发布配置上得到了这个警告。我们开始研究这两个配置之间的差异,我们发现优化复选框是为什么我们在发布时得到这个警告的原因,而不是在调试期间。
我们有下面的配置。
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>当我们为调试将优化值设置为true时,我们还会发出CA警告。当我们把它设为假的时候,警告就消失了。这也只适用于警告CA1806。不管优化值如何,其他CA警告都会正确显示。
触发此警告的代码如下所示。这只是测试代码,但它模拟了我们的真实情况。已分配默认值但从未在任何代码中使用的变量。
public CourseService(IOrtContext context)
{
this.context = context;
var defaultDate = new DateTime(1900, 1, 1);
}那么,有谁知道为什么CA1806依赖于是否启用了优化呢?
发布于 2015-06-22 09:37:18
我相信这是因为优化器完全避免了分配给defaultDate。
在调试模式下,一个新的DateTime被实例化并分配给defaultDate局部变量:
var defaultDate = new DateTime(1900, 1, 1);赋值被视为DateTime实例的“使用”,因此不会引发CA1806,即使随后不使用defaultDate。
另一方面,优化器在发布模式下优化分配(和局部变量):
/* var defaultDate = */ new DateTime(1900, 1, 1);因此,DateTime实例不再被视为“已使用”,而引发了CA1806。
发布于 2015-06-22 09:36:50
随意扔石头..。更简单的调试代码:http://goo.gl/8TXmE9和版本:http://goo.gl/XRBfQp。
在调试模式中,局部变量的生存期被“延长”到方法的结束,这样它们就更容易调试。在发布模式下,这种情况不会发生。变量被积极地解除分配。如果在调试模式或发布模式下编译程序并尝试调试它,则可以看到它.在发布模式中,有些变量有时无法访问,因为它们已经结束了它们的生命周期。
这可以在发行版IL代码中看到:
IL_0007: newobj instance void [mscorlib]System.DateTime::.ctor(int32, int32, int32)
IL_000c: popnew DateTime()的返回将立即从堆栈中退出。CA1806可以很容易地检测到它。
在调试模式下,该值永远不会从堆栈中弹出。一个检查它是否在某个地方使用的分析将是相当复杂的,而且很可能它还没有完成。
https://stackoverflow.com/questions/30976417
复制相似问题