C函数调用后跟逗号分隔符

时间:2015-09-30 15:24:51

标签: c language-design

我正在阅读一些关于编写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时才会出现)

4 个答案:

答案 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

所以,是的,逗号运算符确实有它的位置,但是很少(如果有的话)需要它。