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

C function call followed by a comma separator

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

foo,(1); 先计算 foo 什么也不做,然后计算 (1) 什么也不做。

逗号运算符很有用,例如,当您在 for 循环中执行多项操作时。

int i, j;
for (i = 0, j = 1; i < 10; i++, j *= 2) {
    printf("%d %d\n", i, j);
}
return foo,(1);

相当于:

foo; // Nothing happens. This does not call the function.
return (1);

也许你打算使用:

foo(1);
return 1;

C 是一种简单、极简主义的语言,程序员应该知道他们在做什么。

在 C 中,类型很容易相互转换,原始的 C 甚至没有函数声明——程序员应该知道如何调用每个函数以及使用什么参数。

C 是 Unix 的编程语言,

"UNIX was not designed to stop you from doing stupid things, because that would also stop you from doing clever things."—Doug Gwyn (https://en.wikiquote.org/wiki/Unix)

作为奖励,如果编译器不试图变得聪明,编译会非常快。

C++ 对此采取了非常不同的方法。

关于,运算符的实际应用,请看: https://en.wikipedia.org/wiki/Comma_operator

The comma operator has relatively limited use cases. Because it discards its first operand, it is generally only useful where the first operand has desirable side effects. Further, because it is rarely used outside of specific idioms, and easily mistaken with other commas or the semicolon, it is potentially confusing and error-prone. Nevertheless, there are certain circumstances where it is commonly used, notably in for loops and in SFINAE (http://en.cppreference.com/w/cpp/language/sfinae). For embedded systems which may have limited debugging capabilities, the comma operator can be used in combination with a macro to seamlessly override a function call, to insert code just before the function call.

练习和示例代码似乎是专门设计来突出阅读时的特定用途、陷阱和人为错误的,一系列操作与 comma operator 链接在一起。

逗号运算符没有任何问题,但它更像是一种快捷方式或技巧,可以节省一两行代码并避免将两个表达式循环或条件用大括号括起来。

您在练习中遇到了作者希望您遇到的问题。由于逗号运算符,foo 后面没有括号,您的眼睛很快就看清了这一事实,唯一适用的 return 是 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

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