gpt4 book ai didi

c# - MSIL 或 native 代码中的 "Unreachable code detected"

转载 作者:太空狗 更新时间:2023-10-29 22:11:08 29 4
gpt4 key购买 nike

编译器是否在运行时编译 MSIL 或 native 代码中的“无法访问的代码”?

最佳答案

这个问题有点不清楚,但我会试一试。

首先,Adam 的回答是正确的,因为编译器根据“优化”开关是打开还是关闭发出的 IL 有所不同。编译器在优化开关打开的情况下更积极地删除无法访问的代码。

有两种相关的无法访问的代码。首先是法律上无法访问的代码;也就是说,C# 语言规范调用为无法访问 的代码。第二,存在事实上无法访问的代码;那是 C# 规范没有标明为无法访问但仍然无法访问的代码。在后一种无法访问的代码中,存在优化器已知无法访问的代码,以及优化器未知无法访问的代码。 p>

编译器通常总是删除法律上无法访问的代码,但只有在打开优化器时才删除事实上无法访问的代码。

下面是每个示例:

int x = 123;
int y = 0;
if (false) Console.WriteLine(1);
if (x * 0 != 0) Console.WriteLine(2);
if (x * y != 0) Console.WriteLine(3);

所有三个 Console.WriteLine 都无法访问。第一个是法律上无法访问的; C# 编译器规定,出于明确赋值检查的目的,必须将此代码视为不可访问。

后两个法律上可达但事实上不可达。必须检查它们是否存在明确的分配错误,但允许优化器删除它们。

在这两种情况中,优化器检测到 (2) 情况而不是 (3) 情况。优化器知道整数乘以零始终为零,因此条件始终为假,因此它删除了整个语句。

在 (3) 情况下,优化器不会跟踪分配给 y 的可能值,并确定 y 在乘法点始终为零。即使你我都知道结果是无法达到的,但优化器并不知道这一点。

关于明确赋值检查的部分是这样的:如果你有一个无法访问的语句,那么所有局部变量都被认为在该语句中被赋值,并且所有赋值都被认为没有发生:

int z;
if (false) z = 123;
Console.WriteLine(z); // Error
if (false) Console.WriteLine(z); // Legal

第一次使用是非法的,因为z在使用的时候还没有明确赋值。第二种用法是非法的,因为代码甚至无法访问; z 在分配之前不能使用,因为控制永远不会到达那里!

C# 2 有一些错误,混淆了两种可达性。在 C# 2 中,您可以这样做:

int x = 123;
int z;
if (x * 0 != 0) Console.WriteLine(z);

并且编译器不会提示,即使法律上对 Console.WriteLine 的调用是可达的。我在 C# 3.0 中修复了这个问题,我们进行了重大更改。

请注意,我们保留随时更改不可达代码检测器和代码生成器工作方式的权利;我们可能会决定始终发出无法访问的代码或从不发出它或其他任何东西。

关于c# - MSIL 或 native 代码中的 "Unreachable code detected",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8643990/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com