C程序中的#line意义何在
在学习一些项目源代码时,看到了大量的#line定义,小人不才,语法搜搜是大概懂了,可问个为什么,却难道了自己。
#line是C语言预处理器,语法格式为:
#line number “filename”
如 #line 123 “file.c”
意思就是改变__LINE__和__FILE__宏内容。
当在程序中使用这两个宏的时候,就会因为#line的定义而改变,例子很简单,我就不列举了,不明白的朋友可以自己试试,加入#line后,打印这两个宏的内容。
这两个宏是永久被改变的,会影响当前的c文件一直到文件末尾。
回到原来的项目源代码中,源代码部分片段:
#line 357 "..\gram\sprt.y"{yyval.node = alloc_tree_cell(LNB, yyvsp[-3].str);yyval.node->type = NODE_ARRAY_EL;yyval.node->link[0] = yyvsp[-1].node;;break;}case 72:#line 366 "..\gram\sprt.y"{ yyval.node = alloc_expr_cell(LNB, EXPR_INCR, NULL, yyvsp[0].node); ;break;}case 73:#line 367 "..\gram\sprt.y"{yyval.node = alloc_expr_cell(LNB, EXPR_DECR, NULL, yyvsp[0].node); ;break;}
源程序中,有大量这种代码,和#line,在没查资料前,我一直以为#line是链接到外部文件的一种用法,后来才发现,这种做法仅仅是为了满足调试需要,并且,发布产品时,完全可以全部删除。
在继续阅读并搜罗资料后才得知,这是一组叫做语法解析器生成的代码,OK,看到这里,我就明白了很多了。
首先,#line是改变__LINE__和__FILE__宏的,这两个宏通常用来调试定位问题。
在平常项目开发中,可能用到的不多,甚至是根本不需要,因为我尝试了很多种方法,如宏,函数,动态库等方式,来探讨#line的意义所在,都没能找到原因,后来知晓了分析器后,才得知。
首先介绍两个程序,一个是Flex,一个是Bison。
Flex是词法分析器,它可以根据用户的输入,依据一定的规则(Flex语法)将输入拆分成各个有效片段。
Bison是语法分析器,它可以根据用户的输入,依据一定的规则(Bison语法)将输入的一组文本分析成语法树,并解释执行。
业界人士,通常用Flex和Bison共同来开发语法解释器,例如Nessus的攻击脚本,Unity3D的Action脚本等。
大致了解了Flex和Bison后,进行了一些实践,#line在这里面就显得有为重要了,它可以帮助你处理编译链接时的错误定位,因为你可能写了一个语法哪怕是%{ }%,都会生成上千行的代码。
什么时候使用#line,我思考后总结了一下:
其一,当你给用户提供一些脚本支持,语法解释等工具集时,需要这种#line来帮助用户定位问题。
其二,当你给用户提供一系列API或SDK时,当用户在使用API时,可能需要#line来帮助用户定位问题。
其三,#line不仅仅能改变__LINE__,__FILE__宏,它可以在用户对代码进行编译链接时,显示到错误列表中。
虽然在实际的开发中,基本不用到,但是相对了解下,说不定哪一天需要用Flex和Bison开发属于自己的脚本语言。
小提示:这是语法分析器,如果有兴趣开发语言的朋友们,关于语法高亮,可以使用 Scintilla,它也是开源项目,可以自定义语法高亮,智能提示,Notepad++就是用它做的,关于它的用法以后有机会给大家介绍。
C程序中的#line意义何在相关推荐
- 设置程序中的html,如何在Behat中为HTML格式化程序设置自定义模板
您可以从现有HtmlFormatter扩展自定义类,以明确设置您的html模板. PHP 强> namespace Behat\Behat\Formatter; use Behat\Behat\ ...
- 分数在c语言程序中怎么输入,如何在c语言中实现分数相加,以分数形式输出,并化为最简...
完整的C程序: #include "stdio.h" /* 分数结构 */ typedef struct { int numerator;/* 分子 */ int denomina ...
- 如何在Java程序中调用Python算法脚本,重点讲Demo,不墨迹理论
原创博文,欢迎转载,转载时请务必附上博文链接,感谢您的尊重. 前言 通过本篇,你将初步认识在Java程序中简单调用.py脚本文件的方法,附带入门的Demo实例讲解,更深入的理解还需要进一步学习. 最近 ...
- graphql redux_如何在Redux应用程序中使用GraphQL
graphql redux by Howon Song 通过宋颂恩 如何在Redux应用程序中使用GraphQL (How to use GraphQL in your Redux app) Fetc ...
- 如何在Web应用程序中使用TWAIN驱动程序的自定义功能?
如何在Web应用程序中使用TWAIN驱动程序的自定义功能?接下来跟着小编一起来看看如何去实现. 本文适用于以下产品: Dynamic Web TWAIN v7 以上 ImageCapture Suit ...
- 如何在Spring Boot应用程序中使用配置文件
你好朋友, 在本教程中,我们将学习如何在Spring Boot应用程序中使用配置文件. 我们将在本教程中讨论以下几点: 1.什么是Spring Boot Profile,为什么我们需要分析 2.如何使 ...
- kotlin数据库_如何在Kotlin应用程序中使用Xodus数据库
kotlin数据库 I want to show you how to use one of my favorite database choices for Kotlin applications. ...
- chrome麦克风权限_如何在Chrome扩展程序中处理麦克风输入权限和语音识别
chrome麦克风权限 by Palash Taneja 由Palash Taneja 如何在Chrome扩展程序中处理麦克风输入权限和语音识别 (How to handle mic input pe ...
- react 交互_如何在React应用程序中跟踪用户交互
react 交互 by Faouzi Oudouh 通过Faouzi Oudouh 如何在React应用程序中跟踪用户交互 (How to track user interactions in you ...
最新文章
- 高并发场景下的限流策略
- 华为鸿蒙osbeta多场景展示,华为发布鸿蒙系统:全场景分布式OS
- (0055)iOS开发之dealloc认识
- Processing 状态量控制动画技巧
- 学python编程-趣学Python编程
- c++ shared_ptr的使用
- [转]MyBatis的foreach语句详解
- JavaScript神奇的魔法代码
- LIBSVM在MATLAB中的使用及SVM最优参数选取示例代码
- 生产中k8s适合mysql_在K8S集群中构建复杂的MySQL单实例数据库
- code css怎么拿不到div_哈登和威少再怎么努力,也追不上杜兰特,因为刷子是拿不到冠军的...
- Spring Security Oauth2 (二) 代码 授权码模式
- BZOJ2957楼房重建
- 电脑摄像头未能创建连接服务器,Win7摄像头提示"未能创建视频预览"的原因及解决方法...
- 经典的SharePoint 2010升级中的多核CPU冲突问题
- sql 整改措施 注入_记一次Sql注入 解决方案
- Leetcode 刷题笔记(十六) —— 二叉树篇之二叉搜索树的属性
- php批量导入txt文件,如何把一个文本文件中的十几万数据快速的导入到sql表中
- oracle dba_hist_snapshot,通过dba_hist_*来进行诊断
- 不可不知的P2P(Peer-To-Peer)