C++中不带括号的函数调用

4

在编程时,我没有在函数调用后加括号,但只收到了一个警告,我忽略了它:

main.cpp:7:15: warning: expression result unused [-Wunused-value]
                if (i == 0) clearDisplay;
                            ^~~~~~~~~~~~

同样的事情也会在仅进行此操作时发生。
int i = 0;
i;

为什么这不是编译错误?
#include <iostream>

void clearDisplay(void);

int main(void){
    for(int i = 0; i < 2; i++){
        if (i == 0) clearDisplay;
    }
}

void clearDisplay(void){
    std::cout << "test" << std::endl;
}

编辑:与g++“不带括号调用”函数(不是f()而是f;)。为什么总是返回1?相反,我不问为什么它会被隐式转换为数字,而是为什么编译器不像对if(i=0)if(i==0)那样发出警告。


这里不清楚需要纠正什么误解。为什么你认为这应该是编译器错误? - David Schwartz
2
https://dev59.com/X2Qn5IYBdhLWcg3wIkMF - Bun
省略括号有什么问题吗?还是那只是附带的部分? - Joel Cornett
@joel-cornett 意外的 - mischnic
3个回答

8
您可以将clearDisplay视为函数的地址。关键是,它将具有非零数值,并且由单个变量组成的语句在语法上是正确的。

为什么我可以写 i; 而且它是正确的?这并没有任何区别。 - mischnic
1
只要已经声明了变量i,那么i;编译也是可以通过的。 - Bathsheba

4

这就是为什么这不是编译器错误的原因:

for(int i = 0; i < 2; i++){

看一下i++。这是一个表达式,你完全忽略了它的结果。但这是完全合法的。为什么?因为你可以忽略表达式的结果。

为了有帮助性,编译器会在你忽略没有副作用的表达式的结果时发出警告。但如果有一条语言规则规定忽略没有副作用的表达式是非法的,那就需要编译器完美地判断表达式是否具有副作用,而这基本上是不可能的。


i++i = i + 1; 是一样的,因为它改变了 i 的值,所以不会被忽略。 - mischnic
哦,但是 i++;i; 相比确实有所不同。而且 i = i + 1 实际上返回的是 i+1,设置了新值并返回新值。 - mischnic
1
没错。因此,C++必须允许您忽略表达式的结果。当我们想要评估表达式的副作用时,我们经常会忽略表达式的结果。但是,为了友好起见,编译器应该在看到您忽略它们知道没有副作用的表达式的结果时发出警告,因为这似乎是毫无意义的。 - David Schwartz
1
@mischnic,类似的用法是调用一个函数并忽略返回值。 - phuclv
不,这里的问题是expression;是C和C++中的有效语句。无论表达式的副作用如何,您都要丢弃结果。i = i + 1是一个表达式,因为它返回一个值,您可以在后续表达式中使用它,例如if (i = i + 1)j = i = i + 1... - phuclv
显示剩余5条评论

2
这是一个简要的解释。
就像这个表达式一样:
i;

只是引用变量i而没有实际使用它,这个表达式:

clearDisplay;

这里的简单指的是不实际调用clearDisplay函数,只是提到它。


为什么我可以在不做任何事情的情况下引用 i - mischnic
@mischnic 我不知道。我会说这只是C++的另一个缺陷。其他语言如Java不允许你这样做。 - Sam Estep
是的,通常我使用Java,这也是我偶然发现这个的原因。 - mischnic
1
不要忘记,有些编译器实际上在这样做时会产生代码。尝试使用gcc(4.8)当i是易失性变量时,你将获得加载i值的实际代码(clang不会产生代码但会警告该问题)。 - dhke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接