【问题标题】:Possible different behaviors for C# in debug and release buildC# 在调试和发布版本中可能的不同行为
【发布时间】:2018-01-11 20:42:21
【问题描述】:

在 C++ 中,编译器优化可能会利用程序中未定义的行为(如有符号整数溢出和取消引用空指针)产生“意外”的程序行为。如果在生产中使用发布版本,那么在发布版本中测试程序很重要。

在 C# 中,未定义的行为很少见。除了

  1. 不安全的代码
  2. 多线程计时
  3. 调试/发布模式启用/禁用代码(例如#if)

优化能否像 C++ 一样产生不同的程序行为?

【问题讨论】:

  • 例如在 UWP 项目中,release 中的编译与 debug 中的编译有很大不同(因为 .NET 原生工具链),您应该始终测试 release 版本。还有一些您应该注意的开关,例如#if DEBUG。我想说,测试发布版本总是一个好习惯。
  • stack may collapse due to optimization。关于tail call optimization 的链接文章提到了各种会阻止优化以防止行为差异的条件,但是如果您的应用在未覆盖的情况下依赖调用堆栈条件,您将获得不同的行为

标签: c# testing compilation release compiler-optimization


【解决方案1】:

这与多线程时序有关:在发布模式下,编译器可能会执行某些优化,通过重新排列指令或用常量替换值来改变代码的运行时行为(包括在看似正确的代码中引入无限循环)。这是关于易失性与非易失性内存读取的related question,正如 Hans 在 cmets 中指出的那样,an article from The Daily WTF 关于 C# 编译器将变量替换为常量值作为优化。

【讨论】:

  • 我认为您的意思是“缺少内存同步”。 Violatile 对此不利。 Lock 通常要好得多。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-17
  • 1970-01-01
  • 1970-01-01
  • 2012-10-11
  • 1970-01-01
  • 1970-01-01
  • 2020-07-05
相关资源
最近更新 更多