【问题标题】:Why can I compile a code with 2 returns?为什么我可以编译带有 2 个返回的代码?
【发布时间】:2017-04-12 14:15:38
【问题描述】:

由于我来自 java 岛,我很奇怪为什么编译器没有警告无法访问的代码,例如:

int main(int argc, char** argV)
{

    std::list<int> lst = {1,2,3,4};

    return 0;



    std::cout << "Done!!!" << std::endl;
    return 0;
}

我的问题:

为什么我可以编译一个有 2 个返回的代码?

我的编译器是 c++11 的 gcc,在 Windows 上,代码块

【问题讨论】:

  • 你能想出一个你不能这样做的原因吗?
  • why the compiler doesnt warns 你的警告级别设置是...?

标签: c++ codeblocks compiler-warnings unreachable-code


【解决方案1】:

我很奇怪为什么编译器不会以类似的方式警告无法访问的代码

gcc documentaion 中对警告进行了很好的解释:

-Wunreachable-code

如果编译器检测到代码永远不会被执行,则发出警告。此选项旨在在编译器检测到时发出警告 至少一整行源代码永远不会被执行, 因为某些条件永远不会满足,或者因为它是在一个 永远不会返回的过程。

此选项可能会产生警告,即使存在 是在哪些情况下受影响的线路的一部分可以 已执行,因此在删除明显无法访问时应小心 代码。

例如,当一个函数被内联时,一个警告可能意味着 仅在函数的一个内联副本中无法访问行。

此选项不是 -Wall 的一部分,因为在调试版本中 一个程序通常有大量的代码检查正确 程序的功能,并且希望是无法访问的,因为 程序确实有效。无法访问代码的另一个常见用途是 提供在编译时可选择的行为。

尽管 g++ 5.1.0 不会对此代码产生任何警告,即使启用了此选项。

【讨论】:

    【解决方案2】:

    为什么不能编译具有多个返回的代码? 因为代码无法访问?大多数编译器会为此发出警告。

    但是,我经常看到这样的代码:

       if(a)
       {
          // Do stuff
       }
       else
       {
          // Do other stuff
    
          if(b)
          {
              // Do more stuff
          }
          else
          {
              // Do other more stuff
          }
       }
    

    这可以简化为

       if(a)
       {
          // Do stuff
          return;
       }
    
       // Do other stuff
    
       if(b)
       {
          // Do more stuff
          return;
       }
    
       // Do other more stuff
    

    大约十年前,人们不赞成在方法函数中有多个返回值,但现在没有理由继续反对现代编译器。

    【讨论】:

      【解决方案3】:

      因为这部分

      std::cout << "Done!!!" << std::endl;
      return 0;
      

      将永远不会因为第一个 return 语句而被调用,但这不是中止编译的错误,而是编译器可能会发出警告,具体取决于您使用的编译器(例如,Microsoft 的 VC++ 编译器会警告您)。

      【讨论】:

        【解决方案4】:

        无法访问的代码不是 C++ 中的编译错误,但通常会给出警告,具体取决于您的编译器和标志。

        您可以在调用编译器时尝试添加 -Wall 选项。这会 激活许多有用的警告。

        【讨论】:

        • - 检查墙!
        • 它需要 -Wunreachable-code 不包含在 -Wall 中
        【解决方案5】:

        主要是因为编译器通常无法确定。 (在 Java 中已经尝试过这样做,但已经确定了定义 可达性 的标准。)

        在这种情况下,确实很明显。

        一些编译器确实会发出可达性警告,但 C++ 标准并不要求这样做。

        如果不参考以下内容,关于可达性的答案是不完整的:https://en.wikipedia.org/wiki/Halting_problem

        作为对 Java 的最后评论,请考虑以下两个 Java sn-ps:

        if (true){
            return;
        }
        ; // this statement is defined to be reachable
        

        while (true){
            return;
        }
        ; // this statement is defined to be unreachable
        

        以我的拙见,两全其美。

        【讨论】:

        • 相关:Java 警告过于频繁,因为就像所说的 100% 正确是不可能的。不仅适用于可访问性,还适用于没有初始化的代码路径等。
        【解决方案6】:

        这有两个原因:

        1. C++ 有很多标准(c++11、c++14、c++17 等),与 java 不同(java 在标准上非常严格,唯一与 java 真正重要的是你的版本using),因此,一些编译器可能会警告您无法访问的代码,而其他编译器可能不会。

        2. return 0 之后的语句虽然在逻辑上不可达,但不会导致歧义、语法错误等任何致命错误,并且可以轻松编译(如果编译器愿意的话;))。

        【讨论】:

        • C++ has many standards (c++11, c++14, c++17 etc. ) unlike java 与 Java 不同。 Java语言也有版本,不等于软件版本。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-24
        相关资源
        最近更新 更多