#line指令和实际用法

时间:2014-11-25 09:38:48

标签: c c-preprocessor bison yacc preprocessor-directive

许多 C 书中很少提及#line指令。

他们中的许多人说这个指令是由野牛工具的yacc使用但不是 展示任何实际例子。

任何人都可以向我展示这个指令的一些真实用法或者让我变得实用 野牛或yacc使用的例子?

1 个答案:

答案 0 :(得分:3)

任何从其他文件中的其他内容生成C(或C ++)代码的程序或脚本也应该发出大量#line指令(将生成的C行关联到该另一个文件中的位置)。

这对诊断消息和调试器非常有用。

例如,在某个example.y文件上运行bison并查看生成的C代码,或者构建,安装和使用MELT(一种特定于域的语言来扩展{{3}查看它从.melt文件生成的许多C ++文件。您将在生成的代码中找到类似

的内容
#ifndef MELTGCC_NOLINENUMBERING
#line 63   "warmelt-outobj.melt" /**::procdecl::**/
#endif /*MELTGCC_NOLINENUMBERING*/
MELT_EXTERN melt_ptr_t MELT_MODULE_VISIBILITY meltrout_2_WARMELTmiOUTOBJ_OUTPUT_DESCRIPTIVE_COMMENT(meltclosure_ptr_t meltclosp_, melt_ptr_t meltfirstargp_, const melt_argdescr_cell_t meltxargdescr_[], union meltparam_un *meltxargtab_, const melt_argdescr_cell_t meltxresdescr_[], union meltparam_un *meltxrestab_);

 /*getarg#0*/
 MELT_LOCATION("warmelt-outobj.melt:63:/ getarg");
#ifndef MELTGCC_NOLINENUMBERING
#line 63   "warmelt-outobj.melt" /**::getarg::**/
#endif /*MELTGCC_NOLINENUMBERING*/
 /*_.SEXP__V2*/ meltfptr[1] = (melt_ptr_t) meltfirstargp_;

 /*getarg#1*/
 /*^getarg*/
#ifndef MELTGCC_NOLINENUMBERING
#line 63
#endif
  if (meltxargdescr_[0] != MELTBPAR_PTR) goto meltlab_endgetargs;
  /*_.ENV__V3*/ meltfptr[2] = (meltxargtab_[0].meltbp_aptr) ? (*(meltxargtab_[0].meltbp_aptr)) : NULL;
  gcc_assert(melt_discr((melt_ptr_t)(/*_.ENV__V3*/ meltfptr[2])) != NULL);

以及文件warmelt-outobj.melt的第63行和第13行

(defmacro output_descriptive_comment  (sexp env mexpander modctx)
    (let ( (sloc (get_field :loca_location sexp))
           (scont (get_field :sexp_contents sexp))
           (xargs (expand_restlist_as_tuple scont  env mexpander modctx))
           (argout (multiple_nth xargs 0))
           (argobj (multiple_nth xargs 1))
           )
      (when (!=i (multiple_length xargs) 2)
        (error_at sloc "MELT output_descriptive_comment needs two arguments")
        (return))
BTW,根据经验,当您开发严格的C或C ++代码生成器时,需要发出正确的#line指令,这是代码生成器中的一个重要负担。这可能需要大量的工作。