为什么这段代码片段可以编译?

11
为什么以下代码可以编译?
#include <stdio.h>

int main(void) {
    getchar;
}

20
因为它没有错误? - Jey Geethan
归根结底,问题在于getchar是否允许作为宏定义。如果允许的话,那么这段代码可能是不正确的。 - Alexandre C.
1
这个问题很尴尬。三年前的我真是个白痴。 - missingfaktor
@missingfaktor 不是很确切——这是一个合理的问题。我期望会有“可能没有效果的表达式”或其他警告(至少),但这就是生活。 - 3Dave
3个回答

28

因为函数名是指向这些函数的函数指针的别名,而这些函数指针本身就像整数一样也是值。这在语义上非常类似于

#include <stdio.h>

int main(void) {
    42;
}

这是有效的,但毫无意义。


2
非常烦人!!!打"int x = getX"而不是"x = getX()"会很愉快地工作,并将一些随机地址值放入x。 - Martin Beckett
1
@Rahul:那不是一种非常多语言的态度! - Tarydon
6
任何一款好的编译器都会对这种赋值发出警告。如果你的编译器没有发出警告,请换一个更好的(或者不要禁用所有警告——特别是在C语言中,通常应启用所有警告并将它们视为错误)。 - Jerry Coffin
1
@Rahul - 多语言编程,真是太棒了!我一直认为多语言是指口语,而多语种则是指书面语言(因此也包括代码),但现在看来我是在这些词中加入了本不存在的含义。 - jball
@Jerry:一个像样的编译器会发出错误,因为C语言不允许整数和指针类型之间的隐式转换。不幸的是,大多数现实世界中的编译器都缺乏基本的体面... - R.. GitHub STOP HELPING ICE
显示剩余4条评论

13

同样的道理,1;可以编译通过,getchar只是一个函数地址。结果被计算后就会被丢弃。在语言规范中,这被称为“表达式语句”。


2

C语言很奇怪,这段代码虽然能编译通过,但会产生段错误(segfault)。 记录一下,这是C语言历史上最小的段错误。

main;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接