if .. else number 小于,无法访问的代码

Posted

技术标签:

【中文标题】if .. else number 小于,无法访问的代码【英文标题】:If .. else number is smaller than, unreachable code 【发布时间】:2012-10-20 21:55:31 【问题描述】:

假设我们有以下 C(或类似语言)代码:

if (x < 10)
  do_work1();
else if (x < 5)
  do_work2();

在某些情况下会执行此条件的第二个分支吗?编译器会警告无法访问的代码吗?

【问题讨论】:

不,它不会被执行。大多数 ide 会警告无法访问的代码。 类似的语言可能会超载 &gt; 并让它做意想不到的事情。 我能想到的另一种情况是,如果 x 是一个全局变量,并且您有另一个线程可以将最初大于 10 的 x 的值更改为不幸的情况下第一次测试后小于5的值。例如x 开头是 11。 Thread1 进行第一次测试 if (x &lt; 10) 为假,之后,Thread2 将 x 的值更改为 4。 例如,如果x 是一个易失性的并且在if 部分之后 而在else if 部分之前 更改,则在某些情况下可能会执行 else 部分。像这样的异步更改想起来有点离谱,但肯定是可能的。 @AnthonyPegram 当然,如果你这样做,你所有的同事都会准备好勒死你...... 【参考方案1】:

Will the second branch of condition be executed in some case?

是的,有可能,这取决于代码中的其他内容以及编译器选择对您的代码执行的操作。

Shouldn't compiler warn about unreachable code?

不,它不能,因为不能保证它是不可访问的

以此为例:

int x = 11;

void* change_x()
   while(1)
      x = 3;


int main(void) 

    pthread_t cxt;
    int y = 0;
    pthread_create(&cxt, NULL, change_x, NULL);
    while(1)
        if(x < 10)
            printf("x is less than ten!\n");
        else if (x < 5)
            printf("x is less than 5!\n");
            exit(1);
        
        else if(y == 0)    // The check for y is only in here so we don't kill
                            // ourselves reading "x is greater than 10" while waiting
                            // for the race condition
            printf("x is greater than 10!\n");
            y = 1;
        
        x = 11;
    

    return 0;

还有输出:

mike@linux-4puc:~> ./a.out 
x is greater than 10!
x is less than 5!      <-- Look, we hit the "unreachable code"

【讨论】:

@halex - 你提出了一个很好的观点,值得举例说明。我有几分钟的空闲时间:) 没有任何 volatile 属性(对于 C11 之前的编译器)或内存屏障,编译器不必担心 printf("x is less than 5!\n"); 并且确实会将 main() 优化为目标代码,甚至包含该语句,从而向您显示它对可能到达的语句的关心程度。编译器不警告的原因不是“不能保证它不可达”,因为它对于定义的执行是不可达的,编译器只关心定义的执行。 来自 C11 的 J.2 部分未定义行为:“程序的执行包含数据竞争 (5.1.2.4)。” 很好的例子。这就是我想听到的...谢谢 @PascalCuoq - 我想我以同样的方式看待这个问题,但语义不同。 “我不保证您会点击该代码”,这意味着您可能会或可能不会点击它......即。无法说代码是否可以访问。 “未定义的行为”是同一回事,不可能说会发生什么,或者在这种情况下代码是否可以访问。我可以更新我的措辞方式,但我觉得意思是(或应该是)相同【参考方案2】: 如果 x 是一个局部变量,那么我看不出有任何方法可以执行 do_work2。 如果 x 是全局变量或在多个线程之间共享,则可以执行 do_work2

一般无法证明代码是否可达。编译器可以有一些简单的、可理解的和快速检查的规则来检测简单的无法访问代码的情况。它不应该包括一个缓慢而复杂的求解系统,只有有时有效。

如果您想进行额外检查,请使用外部工具。

【讨论】:

【参考方案3】:

不,编译器不会为此代码生成任何警告(代码无法访问)。当你无条件使用 return 时,这种警告通常会出现。

喜欢

int function()

int x;
return 0;
x=35;

在这种情况下,它会给你警告。

【讨论】:

什么是“编译器”?我的几个编译器确实对第二行发出警告:“代码没有影响”/“无法访问的代码”。但是他们当然没有必须发出警告,警告的定义是:最有可能是错误但不违反C标准的东西。【参考方案4】:

不会执行第二个分支,并且编译器不应警告无法访问的代码。

【讨论】:

The second branch will not be executed, 你确定要这样无条件地声明吗? sn-p OP 给出的代码不足以确定它不会被执行

以上是关于if .. else number 小于,无法访问的代码的主要内容,如果未能解决你的问题,请参考以下文章

无法从 if 正文访问函数内部声明的变量

使用 if/else 的过程

Factorialize a Number

shell中 if else以及大于小于等于逻辑表达式介绍

在 PHP 中使用 if / else 检查 SQL 查询

条件判断和循环控制语句