我正在阅读一些关于编写C程序时应该避免的错误的材料,我遇到了以下代码:
#include <stdio.h>
void foo(int param)
{
printf("foo is called\n");
printf("%d\n",param);
}
int main()
{
return foo,(1);
}
上面的代码构建没有错误和警告(它只在-Wall被激活时显示警告)但是当我运行小程序时,没有显示任何内容。由于逗号分隔符,未调用函数 foo 。
我的问题是为什么C标准允许这样的语法?在这种情况下编译器不应该发出错误吗?在哪种情况下,这种语法可以用在一些实际用例中?
提前致谢,
PD:我正在使用GCC 4.8.3
修改
在这种情况下,编译器无法检测到这种情况并发出错误而不是警告(正如我所说,只有在启用-Wall时才会出现)
答案 0 :(得分:5)
return foo,(1);
相当于:
foo; // Nothing happens. This does not call the function.
return (1);
也许您打算使用:
foo(1);
return 1;
答案 1 :(得分:5)
C是一种简单的极简主义语言,程序员应该知道他们在做什么。
在C中,类型很容易相互转换,原始的C甚至没有函数声明 - 程序员应该知道如何调用每个函数以及使用什么参数。
C是Unix的编程语言和
“UNIX并不是为了阻止你做蠢事,因为 这也会阻止你做一些聪明的事情。“ - Doug Gwyn(https://en.wikiquote.org/wiki/Unix)
作为奖励,如果编译器不试图变得聪明,编译可以非常快。
C ++采用了一种截然不同的方法。
至于SortedMap
运算符的实际应用,请看一下:
https://en.wikipedia.org/wiki/Comma_operator
逗号运算符的用例相对有限。 因为它丢弃了它的第一个操作数,所以它通常只是有用的 第一个操作数具有理想的副作用。而且,因为 它很少在特定习语之外使用,很容易被误解 其他逗号或分号,可能会令人困惑 容易出错。然而,在某些情况下,它确实如此 常用,特别是for for循环和SFINAE (http://en.cppreference.com/w/cpp/language/sfinae)。对于嵌入式 可能具有有限调试功能的系统,逗号 运算符可以与宏结合使用 覆盖函数调用,在函数之前插入代码 调用
答案 2 :(得分:4)
foo,(1);
首先评估foo
并且不执行任何操作,然后评估(1)
并且不执行任何操作。
例如,当您在for
循环中执行多项操作时,逗号运算符很有用。
int i, j;
for (i = 0, j = 1; i < 10; i++, j *= 2) {
printf("%d %d\n", i, j);
}
答案 3 :(得分:2)
看来练习和示例代码专门用于突出显示阅读时的特定用途,陷阱和人为错误,以及与comma operator
链接在一起的一系列操作。
逗号运算符没有任何问题,但更多的是保存一行或两行代码的快捷方式或黑客,避免在括号中包装两个表达式循环或条件。
你偶然发现了作家希望你在练习中偶然发现的内容。由于逗号运算符,foo
之后没有括号,您的眼睛正好看过,唯一适用的返回值为1
。
这是一个很好的例子。为什么?已经发生了学习 - 不仅仅是关于逗号操作符,而且您了解到只有在编译代码时使用-Wall
时才会公开警告(您还应该添加-Wextra
)。所有的例子都只能希望这样做。
要完成该示例,请查看该情况下逗号运算符的工作应用程序。 (奖金 - 如果你在编译和运行示例之前抓住了它)
#include <stdio.h>
void foo(int param)
{
printf("foo is called\n");
printf("%d\n",param);
}
int main()
{
//return foo,(1);
return foo(0),1;
}
<强>输出强>
$ ./bin/commafoo
foo is called
0
$ echo $?
1
所以,是的,逗号运算符确实有它的位置,但是很少(如果有的话)需要它。