【问题标题】:How following code compiles in C/C++?以下代码如何在 C/C++ 中编译?
【发布时间】:2012-03-15 09:00:53
【问题描述】:

以下代码打印-10

int x = 10;
-x;
cout << -x << endl;  // printf("%d\n", -x); 

在 C 和 C++ 编译器中都有 (gcc 4.1.2)。我期待第二行出现编译器错误。 可能是基本的东西,但我不理解这种行为。有人可以解释一下吗?

谢谢

【问题讨论】:

  • -x; 否定 x 并丢弃结果。与 x+1; 相同
  • 请注意,在这种情况下,编译器可能会优化整个表达式,因为它没有效果。实际上,我希望任何体面的编译器都会警告您这种声明的无用性。
  • 是的,当我给 -Wall 时,我收到警告:“语句无效”
  • 啊,幸好你总是用-Wall 编译,嗯?也许这里有一个更大的教训......
  • 注意:如果你把警告级别提高,编译器会发出警告。由于警告通常是代码中的逻辑错误(如上),您还可以让编译器将警告视为错误。试试:g++ -Wall -Wextra -Werror &lt;file&gt;.cpp

标签: c++ c operators


【解决方案1】:

语句可以是表达式。此类语句会丢弃表达式的结果,并评估表达式的副作用。

-x; 计算 x 的否定并丢弃结果。

有关更多信息,请阅读 C++ 标准中的 [stmt.expr]

【讨论】:

    【解决方案2】:

    当您执行-x; 时,operator - 会在变量上执行。
    运算符返回否定的值,但不改变对象本身。

    所以因为你不存储运算符的结果,x 本身仍然具有相同的值。

    当您将-x 打印到cout 时,您会看到operator - 的结果返回到operator &lt;&lt;

    【讨论】:

    • operator- 不用于 int 等内置类型。
    【解决方案3】:

    C++ 没有赋值语句或过程调用语句。 它将赋值定义为表达式中的运算符,带有边 效果,并有一个表达式语句。预计 表达式语句中的顶级运算符有侧 效果——它要么修改状态,就像赋值运算符, 或者它调用一个函数。但是语言不需要它,并且 完全合法的没有副作用的表达式语句。

    一个好的编译器会在这种情况下输出警告,因为它几乎 当然是程序员错误(您通常可以通过以下方式关闭警告 如果出于某种原因需要,将结果显式转换为 void 这样的声明——assert 宏经常这样做)。

    【讨论】:

      【解决方案4】:

      第二行对x 没有影响,但已计算。第三对 x 没有影响,但计算的输出被发送到标准输出 std::cout 。为了让事情更容易理解:

      int x=10;
      std::cout << x-10 << std::endl;
      std::cout << x << std::endl; 
      

      将输出 010

      【讨论】:

        猜你喜欢
        • 2013-09-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-06
        相关资源
        最近更新 更多