Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/vim/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
ctags是否支持GCC的固定原型功能?_Gcc_Vim_Ctags - Fatal编程技术网

ctags是否支持GCC的固定原型功能?

ctags是否支持GCC的固定原型功能?,gcc,vim,ctags,Gcc,Vim,Ctags,我发现gcc支持一个奇怪的函数定义,如: static void add_define P3(char *, name, int, nargs, char *, exps) 使用-D_uu_u使用u固定的u原型uu编译。我的vim标记列表插件无法给出正确的结果。我试图在ctags的手册页中找出答案,但找不到 编辑 是的,这很奇怪。宏是 #define P3(t1, v1, t2, v2, t3, v3) (t1 v1, t2 v2, t3 v3) 评论说这是 ANSI/K&R兼容性材料 它打

我发现gcc支持一个奇怪的函数定义,如:

static void add_define P3(char *, name, int, nargs, char *, exps)
使用-D_uu_u使用u固定的u原型uu编译。我的vim标记列表插件无法给出正确的结果。我试图在ctags的手册页中找出答案,但找不到

编辑 是的,这很奇怪。宏是

#define P3(t1, v1, t2, v2, t3, v3) (t1 v1, t2 v2, t3 v3)
评论说这是

ANSI/K&R兼容性材料


它打算将AIX的c编译器xlc与宏定义相结合,如下所示:

#define P3(t1, v1, t2, v2, t3, v3) (t1 v1, t2 v2, t3 v3)
本声明:

static void add_define P3(char *, name, int, nargs, char *, exps);
(我添加了一个尾随分号)扩展为:

static void add_define(char *name, int nargs, char *exps);
这是一个非常普通的函数原型(假设尾随分号)

该宏可能有另一个版本,如下所示:

#define P3(t1, v1, t2, v2, t3, v3) \
    (v1, v2, v3) \
    t1 v1; \
    t2 v2; \
    t3 v3;
这将扩大到:

static void add_define(name, nargs, exps)
char *name;
int nargs;
char *exps
这是一个K&R风格的非原型函数声明

很可能是这样的:

#ifdef __STDC__
#define P3(t1, v1, t2, v2, t3, v3) (t1 v1, t2 v2, t3 v3)
#else
#define P3(t1, v1, t2, v2, t3, v3) \
    (v1, v2, v3) \
    t1 v1; \
    t2 v2; \
    t3 v3;
#endif
以及类似的宏P0、P1、P2等,用于不同数量的参数。或者,正如您在问题中所暗示的,它使用用户定义的宏
\uuuu使用\u固定的\u原型\uuuu
,而不是
\uuu STDC\uuu

这将允许单个声明自动扩展到现代原型或K&R样式的声明;后者只有在非常旧的前ANSI编译器中才是必要的

为了回答标题中的问题(最后!),
ctags
对未预处理的C源代码进行操作。对GNU
ctags
的快速实验表明,它在解释模糊基本语法的宏方面并不特别聪明。它将为宏定义本身生成标记项,但无法识别

static void add_define P3(char *, name, int, nargs, char *, exps) {
    /* ... */
}
作为函数定义。(您可以通过预处理器运行源文件,但是标记会引用预处理文件,这不是特别有用。)原则上,
ctags
应该理解完整的C语法,包括预处理器;实际上,事实并非如此

如果您想让
ctag
为您的源文件生成标记,您需要去掉宏并编写可识别的原型。您将无法使用ANSI之前的编译器编译修改后的源代码,但现在这不太可能成为问题。如果您能够做到这一点,那么生成的代码应该更易于维护


或者,由于
ctags
生成的输出相当简单,因此手动将相关标签添加到
标签
文件应该不会太困难(尽管自动维护可能会很困难)。

奇数声明<代码>名称,
nargs
exps
是类型名称吗?或者你有没有用逗号把名字和类型分开?P3的定义在哪里?它是如何定义的?结尾是否缺少分号?然而,如果不让
ctag
支持这种表示法,就很难理解C。你需要大部分的编译器才能让它工作。为什么你认为P3宏仍然是有益的?为什么不将代码编写为真正的常规函数?哪个编译器不支持标准原型符号?@JonathanLeffler
name
nargs
exps
是变量名。也许你是对的,在阅读之前,我应该把这个该死的东西换成常规函数。我现在明白为什么它是
P3
;它适用于具有3个参数的原型。我想是时候摆脱这种符号了。当然,AIX(xlc)不需要替代符号——非原型形式。虽然这都是事实,并且解释了P3宏的用途,但它并没有真正解决他关于
ctags
@KeithThompson的问题。谢谢,C宏的解释令人印象深刻。