加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 解析一个int(x)参数

发布时间:2020-12-16 05:37:07 所属栏目:百科 来源:网络整理
导读:这里是一个简单的函数,一个int参数: void f(int x) {}f(42); 这里还有一个int参数的函数: void g(int(x)) {}g(42); 现在让我们将x定义为一个类型: typedef int x;void h(int(x)) {}h(42);// warning: passing argument 1 of ‘h’ makes pointer from int
这里是一个简单的函数,一个int参数:
void f(int x) {}

f(42);

这里还有一个int参数的函数:

void g(int(x)) {}

g(42);

现在让我们将x定义为一个类型:

typedef int x;
void h(int(x)) {}

h(42);
// warning: passing argument 1 of ‘h’ makes pointer from integer without a cast

(这是我用gcc 4.8.2观察的行为)

解析器作者如何处理这种情况?

看来经典的流水线Lexer – >解析器 – >语义检查器 – > …在这里不工作

解决方法

你有效地将h定义为:
void h(int(int)) {}

该参数被解释为一个未命名的函数指针,它接受一个int并返回一个int.当您尝试传递42时,编译器会抱怨您正在尝试从一个整数形成一个函数指针.

我想你所要求的是编译器如何处理(未命名)函数指针类型及其可能含糊的解析.您的问题与C中的the most vexing parse有关.

在那里,他们决定,每当函数指针类型和另一种解析方式之间存在歧义时,它将被解释为函数指针.他们做到这一点,因为当你不想让它成为一个函数指针时,有其他的方法可以消除歧义(例如 – 用括号括起来,使用{}初始化语法等).

了解解析器作者如何处理此解析的细节,以下是C11:http://quut.com/c/ANSI-C-grammar-l-2011.html的词法分析器和语法在您的示例中,在typedef之前,x在之后将是一个IDENTIFIER令牌,它将是一个TYPEDEF_NAME令牌,因为分析仪正在通过符号表通知x现在是一种类型.在这种特殊情况下,解析是明确的.在这种情况下,您通过符号表发出的“流水线反馈”发生在这种情况下,在汇编进行时,词汇分析器会被上级影响其输出的上级信息通知上下文.

编辑:These three articles,由OP发现,描述了这个问题,以及它如何被一些C解析器/编译器非常好地解决.基本上,几乎可以指定仅接受/产生合法C语法的上下文无关语法(CFG).通过引入范围查找表,允许词法分析器适当地区分标识符和typedef名称,那么只能接受/产生合法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 */

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读