【问题标题】:Variable declaration as side-effect变量声明作为副作用
【发布时间】:2014-02-03 21:36:21
【问题描述】:

所以我正在查看 C++ 运算符规则,就像我的程序开始表现异常时一样。我遇到了逗号运算符。现在,我知道它在那里有一段时间了,但从未使用过,所以我开始阅读,发现了这个小宝石:

if (int y = f(x), y > x)
{
    // statements that use y
}

我从未想过使用逗号的第一个参数的副作用来获取局部范围的变量,而无需庞大的块分隔代码或重复的函数调用。当然,这一切都让我非常兴奋,我立即跑去尝试。

test_comma.cpp: In function 'int main()':
test_comma.cpp:9:18: error: expected ')' before ',' token
  if (int y = f(x), y > x) {

我在 C 和 C++ 编译器上都试过这个,但他们都不喜欢它。我尝试在外部范围内声明y,并且在if 条件中没有int 的情况下它编译并运行得很好,但这违背了这里逗号的目的。这只是 GCC 实现的怪癖吗?互联网上的观点似乎是这应该是完全有效的 C(在我看来,表面上是 C++)代码;在我见过的任何 GCC 或 C++ 论坛上都没有提及此错误。


编辑:更多信息。我在 Windows 7 64 位上使用 MinGW GCC 4.8.1-4(虽然很明显我的二进制文件是 32 位的;我需要在这些天安装 mingw-w64)。

我也尝试在条件语句之外使用这个技巧,如下所示:

int y = (int z = 5, z);

这引发了两个不同的错误:

test_comma.cpp: In function 'int main()':
test_comma.cpp:9:11: error: expected primary-expression before 'int'
      int y = (int z = 5, z);
       ^
test_comma.cpp:9:11: error: expected ')' before 'int'

在我上面的if 语句中创造性地使用了括号,我也设法在那里得到了同样的错误。

【问题讨论】:

    标签: c++ c gcc comma


    【解决方案1】:

    与其他几个人声称的相反,declarations inside the if conditional are perfectly valid。但是,您的代码不是。

    第一个问题是您实际上并没有使用逗号运算符,而是 [几乎] 试图声明多个变量。 That is not valid in an if conditional。而且,即使它可能的,你的第二个声明无论如何都会被完全破坏,因为你试图重新声明y,你这样做是用>而不是=。这一切都毫无意义。

    下面的代码有点相似:

    if (int y = (f(x), y > x))
    

    现在是 at least it's half-valid,但您使用的 y 未初始化并产生未定义的行为。

    声明和表达式不是一回事,所以下面是完全不同的代码:

    int y = 0;
    if (y = f(x), y > x)
    

    现在,未初始化的变量也没有问题(因为我自己初始化了y),并且您得到了这个“副作用声明”,它不会改变@987654334 的结果值@有条件的。但它几乎像泥一样清澈。看看优先级是如何形成的:

    int y = 0;
    if ((y = f(x)), (y > x))
    

    这不是很直观。

    希望这场彻底的灾难能够成为完全避免这种神秘代码的教训。 :)

    【讨论】:

    • @hacks: Ill-formed;我的第二段适用于此。
    • 我误会了。当然, 在这里不是逗号操作符:)。
    【解决方案2】:

    您不能同时声明变量和应用operator ,,或者您正在声明变量(如果是if,这只是一个原因,因为结果需要解析为bool),或者您正在编写一些语句(还解析为bool),其中可能包含operator ,

    【讨论】:

      【解决方案3】:

      你需要在if条件的顶部声明y:

      int y;

      如果(y=f(x),y>x)

      {

      }

      这将检查 if 条件中定义的最后一个条件,其余的将作为一般语句执行。

      【讨论】:

        猜你喜欢
        • 2019-09-18
        • 2015-10-10
        • 1970-01-01
        • 2018-06-29
        • 2013-07-10
        • 2021-11-30
        • 1970-01-01
        • 2021-11-13
        • 1970-01-01
        相关资源
        最近更新 更多