为什么允许多变量返回语句?

时间:2015-04-06 19:56:31

标签: c++

简单地说,为什么下面的代码会编译?

#include<iostream>

int foo(){
    return 0,1;
}

int main(){
    int a,b = foo();
    std::cout << a << " " << b << std::endl;
    std::cout << foo();
    return 0;
}

我正在使用64位Window的机器,并使用Dev-C ++进行编译(使用MinGW GCC 4.5.2 32位编译器)。

此代码打印以下输出:

2686824 1
1

我强烈怀疑a中包含的值是存储在未初始化变量中的常见垃圾。

this question可以清楚地看出,从函数中返回多个值并不是行业中常见的做法,在学术机构教授的编程课程中肯定会受到劝阻和惩罚。

那么为什么它会起作用?由于我已经成熟为程序员,我已经意识到编译器错误的难以置信的价值,它比链接器或运行时错误更容易理解,并且显然比错误更好。

要明确的是,我更感兴趣的是为什么从语言设计的角度来看这是允许的,而不是编译器如何做其事情的技术细节(除非,在这种情况下,实现现实或技术后果已经做出很难/不可能检测/管理多个return变量。)

是否有一些深奥的案例认为多变量return声明有用?

2 个答案:

答案 0 :(得分:16)

您仍然只返回一个值1

return 0,1;

使用comma operator,其结果是右手边。使用正确的警告级别,您的编译器(至少gcc和clang)将发出警告,因为它的左侧没有效果。

如果您确实想要返回多个值,则可以返回std::tuple(或std::pair):

auto fun () {
    return std::make_tuple(0,1);
}

int main () {
    int a, b;
    std::tie(a,b) = fun();
    // Now a == 0, b == 1
}

C ++ 17中的等效替代:

auto fun () {
    return std::make_tuple(0,1);
}

int main () {
    auto [a,b] = fun();
}

Live

答案 1 :(得分:4)

0,1是一个除了按顺序计算两个表达式并且得到第二个运算符(1)的值之外什么都不做的运算符。因此,return 0,1相当于说return 1

int a,b = foo();创建了两个变量。 a未初始化,b的返回值为foo()

这就是为什么b的值为1而a的值是古怪的(未定义)。


IME,逗号运算符的主要好处是C中的for循环。例如,假设您想要枚举链表的元素。列表没有内置的订单概念,因此您最终会在列表中保留两个位置跟踪器。

for (index = 0, curr_node = list_begin; 
  curr_node != NULL; 
  ++index, curr_node = curr_node->next)
{
  // Stuff
}

这对于可读性来说是一个方便的小技巧,它还保证index / curr_node无论你使用break还是continue做什么都保持同步。