逗号运算符是做什么用的?

40

下面的C/C++代码是做什么用的?

if (blah(), 5) {
    //do something
}

应该在问题中指定语言;即使没有C和C++标签,我认为标记也不足够。 - Mark Baker
@jfm3 对我来说不是作业,但是IRC频道里有人问了这个问题,我觉得这是一个好问题。 @Mark 谢谢,我已经记录下来问题中的语言了。 - Matt
“C/C++”不是一种语言。大多数回答者似乎都集中在逗号运算符重载上,因此涉及到了C ++。这个问题可能需要重新标记。 - unwind
8个回答

66

逗号运算符被应用,值为5用于确定条件语句的真/假。

它将执行blah()函数并返回一些东西(可能是),然后使用逗号运算符,只有值为5的内容被用于确定表达式的真/假值。


请注意,逗号运算符可能会被重载为blah()函数的返回类型(未指定),从而使结果变得不明显。


有趣的是(至少对我来说),当你重载逗号运算符时,操作的顺序显然不能保证。总的来说,我认为我永远不会这样做。 - itsmatt
这让我想起了几天前我写的一个错误:本来想写CAnObject a(d, f);但最终写成了CAnObject a = (d, f);不幸的是,f的类型需要转换为CAnObject。糟糕。 - QBziZ

45

如果逗号运算符没有被重载,那么代码类似于这样:

blah();
if (5) {
  // do something
}

如果逗号运算符被重载,结果将基于该函数。

#include <iostream>
#include <string>

using namespace std;

string blah()
{
    return "blah";
}

bool operator,(const string& key, const int& val) {
    return false;
}

int main (int argc, char * const argv[]) {

    if (blah(), 5) {
        cout << "if block";
    } else {
        cout << "else block";
    }

    return 0;
}

(经过编辑以展示逗号运算符重载场景。感谢David Pierre对此进行评论)


不,C++ 这里有运算符需要考虑。 - David Pierre
是的 - 忘记了在C ++中可以重载逗号运算符。我想这就是这个问题的真正重点! - jop

20
我知道这种代码应该做的一件事情:让码农失业。如果有人写这样的代码,我会很害怕和他共事。

13

在病态情况下,它取决于逗号操作符的执行方式...

class PlaceHolder
{
};

PlaceHolder Blah() { return PlaceHolder(); }

bool operator,(PlaceHolder, int) { return false; }

if (Blah(), 5)
{
    cout << "This will never run.";
}

1

我会说那取决于 blah()。


blah() 将被调用,我们不知道会产生什么副作用。因此,回答“这段代码会做什么?”这个问题是不可能的。 - Ben Hoffstein
我同意你的看法,Ben。没有足够的信息可以确定。 - itsmatt
例如,异常。或者如果您喜欢C语言,goto。 - tfinniga

1

更广义的回答是,逗号运算符(非重载)解析为执行第一部分并返回第二部分。

因此,如果你有(foo(),bar()),两个函数都将被执行,但表达式的值将评估为bar()(表达式的类型也是如此)。

虽然我不会说这样做有公平的用途,但通常认为这是一种难以阅读的代码。主要是因为没有多少语言共享这样的结构。因此,作为个人的经验法则,除非我正在向现有表达式添加代码并且不想完全更改其格式,否则我会避免使用它。

例如:我有一个宏(不讨论是否应该使用宏,有时甚至不是你编写的)

FIND_SOMETHING(X) (x>2) ? find_fruits(x) : find_houses(x)

我通常在赋值中使用它,例如my_possession = FIND_SOMETHING(34);

现在我想为其添加日志以进行调试,但我不能更改查找函数。我可以这样做:

FIND_SOMETHING(X) (x>2)? (LOG("looking for fruits"),find_fruits(x)):(LOG("looking for houses"),find_houses(x))


0

我有时会使用这样的结构来进行调试。当我强制 if 语句无论 blah 的返回值都为 true 时,以便进行调试。显然,这种结构永远不应出现在生产代码中。


0

以下内容假定是C代码,可以是C文件中的代码或者C++文件中的C块:

这是一个无意义的if语句。它会调用blah()函数,但是blah()函数的结果并没有被if语句考虑到。唯一被考虑的是数字5,因此这个if语句总是会被评估为true。也就是说,你可以将这段代码写成:

blah();
// do something

完全没有任何if


是的,不幸的是,有人可能会让blah()返回一个类已经重载了逗号运算符的对象,那么谁知道会发生什么。逗号运算符可能会将某些内容与5进行比较并返回false,完全跳过括号中的代码。 - itsmatt
如果这是C++(即使C++项目中可能有一个普通的C文件),那么会有一个C++标签,但也会有一个C标签,这也可能在extern "C"块内,这种情况下无法进行重载。 - Mecki

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