我面对下一个样本:
#include <stdio.h>
// test multiple return
int foo()
{
return 1,2,3,4,5,6;
}
// main entry point
int main(int argc, char* argv[])
{
printf("foo returns: %d\n", foo());
return 0;
}
编译它,然后运行:
gcc main.cpp -o main
./main
结果令我困惑:
foo returns: 6
问题是:为什么没有编译时错误?
答案 0 :(得分:11)
在此背景下:
return 1,2,3,4,5,6;
实际上是comma operator。它按顺序(从左到右)评估逗号之间的所有内容,并返回最后一个。
这就是它返回并打印6
的原因。 是的,它是有效的代码。这就是没有编译器错误的原因。 (虽然在这种情况下1,2,3,4,5
部分没有做任何事情。)
在C和C ++中,您无法返回多个值。你必须使用结构或类来做到这一点。
答案 1 :(得分:10)
因为您使用的是comma operator:a,b
表达式a
,其中b
和a
是任意的(通常是副作用的)子表达式意味着:评估左边 - 手边a
并放弃其结果(因此仅b
评估副作用),然后评估struct
并将结果作为结果。
您无法从 C 函数返回多项内容。你应该返回,例如聚合(通常是gcc -Wall
)或动态堆分配的指针。
至于问题,编译器为什么不说什么?因为你没有问过它。你真的应该使用g++ -Wall
(对于C代码)或 egor7.c: In function ‘foo’:
egor7.c:6:13: warning: left-hand operand of comma expression has no effect [-Wunused-value]
egor7.c:6:15: warning: left-hand operand of comma expression has no effect [-Wunused-value]
egor7.c:6:17: warning: left-hand operand of comma expression has no effect [-Wunused-value]
egor7.c:6:19: warning: left-hand operand of comma expression has no effect [-Wunused-value]
egor7.c:6:21: warning: left-hand operand of comma expression has no effect [-Wunused-value]
(对于C ++代码)进行编译,然后你会收到警告:
{{1}}
答案 2 :(得分:4)
如有疑问,请使用Clang:
$ clang++ -Weverything test.cpp
test.cpp:4:5: warning: no previous prototype for function 'foo' [-Wmissing-prototypes]
int foo()
^
test.cpp:6:10: warning: expression result unused [-Wunused-value]
return 1,2,3,4,5,6;
^
test.cpp:6:12: warning: expression result unused [-Wunused-value]
return 1,2,3,4,5,6;
^
test.cpp:6:14: warning: expression result unused [-Wunused-value]
return 1,2,3,4,5,6;
^
test.cpp:6:16: warning: expression result unused [-Wunused-value]
return 1,2,3,4,5,6;
^
test.cpp:6:18: warning: expression result unused [-Wunused-value]
return 1,2,3,4,5,6;
^
6 warnings generated.
顾名思义,-Weverything
激活每一个警告。这样您就不必记住他们所在的组。
至于解释:请参阅Mysticial关于逗号运算符及其排序效果的答案。这个运算符的一个有用的例子是:
std::list<Item> list = /**/;
assert(list.size() >= 10);
auto it = list.begin();
for (int i = 0; i < 10; ++i, ++it) {
std::cout << "Item " << i << ": " << *it << "\n";
}
注意for
循环的第3个子句如何使用逗号运算符在单个语句中执行两个操作。
当然,这种语法大多是轶事,所以人们经常会感到惊讶......