您有效地定义h
为:
void h(int(int)) {}
该参数被解释为一个未命名的函数指针,它接受一个int
并返回一个int
。当您尝试传递42
给它时,编译器会抱怨您正在尝试从整数创建函数指针。
我认为您要问的是编译器如何处理(未命名的)函数指针类型及其可能模棱两可的解析。您的问题与C++中最令人头疼的解析有关。
他们在那里决定,只要函数指针类型和另一种解析方式之间存在歧义,就会将其解释为函数指针。他们这样做是因为当您不希望它成为函数指针时,还有其他方法可以消除歧义(例如 - 将其括在括号中,使用 {} 初始化语法等)。
详细了解解析器编写器如何处理此解析,这里是 C11 的词法分析器和语法:http: //quut.com/c/ANSI-C-grammar-l-2011.html在您的示例中,之前typedefx
将是一个IDENTIFIER
标记,而在之后,它将是一个标记,因为分析器是通过现在是一个类型TYPEDEF_NAME
的符号表来通知的。x
在这种特殊情况下,解析是明确的。在这种情况下,您似乎所指的“管道反馈”通过符号表发生,其中词法分析器通过在编译过程中影响其输出的更高级别通知上下文。
编辑: OP 发现的这 三篇 文章描述了这个问题以及一些 C 解析器/编译器如何很好地解决它。基本上,几乎可以指定只接受/生成合法 C 语法的上下文无关语法 (CFG)。通过引入允许词法分析器适当地区分标识符和类型定义名称的范围查找表,然后是只接受/生成合法 C 的 CFG [更重要的是 LALR(1) 解析器(例如 - yacc 生成)]可以指定语法。
这是一个比 OP 更可怕的例子:
typedef int x;
int main() { x x = 5; return x; } /* crazily enough this is legal C syntax and a well formed C program */