禁止使用逗号运算符

Ria*_*iaD 9 c++ comma-operator

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

简化示例:

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
}
Run Code Online (Sandbox Code Playgroud)

是否有可能获得编译错误而不是错误的,难以调试的代码?

thi*_*ton 21

是的,有一个警告.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]
Run Code Online (Sandbox Code Playgroud)

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

return (a *= a, b/2);
Run Code Online (Sandbox Code Playgroud)

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

作为参考,该-Wunused-value手册的完整条目与Mike Seymours的报价突出显示:

只要语句计算明确未使用的结果,就会发出警告.要禁止此警告,请将未使用的表达式转换为void.这包括表达式语句或逗号表达式的左侧,不包含副作用.例如,诸如x [i,j]之类的表达式将导致警告,而x [(void)i,j]则不会.

  • @Nawaz:从技术角度来看,它是否是一个未使用的值(我很确定它是),GCC选项可以捕获它.来自他们的[文件](http://gcc.gnu.org/onlinedocs/gcc-4.6.0/gcc/Warning-Options.html#index-Wunused_002dvalue-322):"这包括表达式陈述或左边 - 逗号表达式的一面,没有任何副作用." (6认同)
  • @Nawaz:当然,但是逗号的左操作数没有效果而被忽略,它被-Wunused-value捕获. (4认同)
  • @Nawaz:他是对的.`a*a`显然是一个未使用的值. (2认同)