我从不使用逗号运算符。
但有时,当我写一些递归时,我会犯一个愚蠢的错误:我忘记了函数名。这就是为什么返回最后一个操作数,而不是递归调用的结果。
简化示例:
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
}
是否有可能出现编译错误而不是错误的、难以调试的代码?
我从不使用逗号运算符。
但有时,当我写一些递归时,我会犯一个愚蠢的错误:我忘记了函数名。这就是为什么返回最后一个操作数,而不是递归调用的结果。
简化示例:
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
}
是否有可能出现编译错误而不是错误的、难以调试的代码?
是的,有一个警告。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] 不会。
gcc 允许您指定-Wunused-value如果逗号运算符的 LHS 没有副作用,它将警告您。