【问题标题】:Disallow using comma operator禁止使用逗号运算符
【发布时间】:2011-11-15 16:49:17
【问题描述】:

我从不使用逗号运算符。
但有时,当我写一些递归时,我会犯一个愚蠢的错误:我忘记了函数名。这就是为什么返回最后一个操作数,而不是递归调用的结果。

简化示例:

int binpow(int a,int b){
    if(!b)
        return 1;
    if(b&1)
        return a*binpow(a,b-1);
    return (a*a,b/2); // comma operator
}

是否可能出现编译错误而不是错误、难以调试的代码?

【问题讨论】:

  • 这太多了。您希望编译器为您完成所有工作?
  • @Nawaz 我想让编译错误尽可能多。
  • @Nawaz,我假设您会取消所有编译器消息? ;-)
  • "return (a*a,b/2); // 逗号运算符" 那行应该对你尖叫,让你的眼睛燃烧起来。您不需要编译器错误,您只需要阅读该死的行。
  • @SteveLorimer 我明白了。但我认为有必要审查代码,最简单的代码审查就会发现这个错误。

标签: c++ comma-operator


【解决方案1】:

是的,有一点需要注意。 gcc 有-Wunused-value 警告(或-Werror 错误)。这将对您的示例生效,因为a*a 无效。编译结果:

test.cpp: In function ‘int binpow(int, int)’:
test.cpp:6:43: warning: left operand of comma operator has no effect [-Wunused-value]

但是,这不会捕获单参数调用和所有参数都有副作用的调用(如++)。例如,如果你的最后一行看起来像

return (a *= a, b/2);

不会触发警告,因为逗号语句的第一部分具有更改a 的效果。虽然这对于编译器来说是可诊断的(分配了一个以后不使用的局部非易失性变量)并且可能会被优化掉,但没有针对它的 gcc 警告。

作为参考,手册的完整 -Wunused-value 条目突出显示了 Mike Seymours 引用:

每当语句计算出明确未使用的结果时发出警告。要抑制此警告,请将未使用的表达式强制转换为 void。 这包括不包含副作用的表达式语句或逗号表达式的左侧。 例如,x[i,j] 等表达式将导致警告,而 x[ (void)i,j] 不会。

【讨论】:

  • @Nawaz:可以,但是逗号左边的操作数没有作用,被忽略,被-Wunused-value捕捉到了。
  • @thton:不,这不是未使用的值。我认为这不会发出任何警告。你自己试过吗?
  • @Nawaz:他是对的。 a*a 显然是一个未使用的值。
  • @Nawaz:无论在技术上它是否是未使用的值(我很确定它是),GCC 选项都会捕获它。来自他们的documentation:“这包括不包含副作用的表达式语句或逗号表达式的左侧。”
  • 当然是未使用的值。告诉我它在哪里被使用;我敢你。
【解决方案2】:

gcc 允许您指定 -Wunused-value,如果逗号运算符的 LHS 没有副作用,它将警告您。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-04
    • 2017-07-11
    • 2010-12-16
    • 1970-01-01
    • 2011-03-08
    • 2020-04-22
    • 2016-08-22
    • 2016-03-13
    相关资源
    最近更新 更多