如何在不使用IDE的情况下自动生成/更新cpp文件中的头文件?

bar*_*baz 18 c++ ide vim makefile

我使用VIM进行C++开发已有很多年了,我不想讨论是否使用IDE或强大的文本编辑器进行软件开发的问题.到目前为止,我主要参与了一个仅限标题的模板库,其中所有内容都是模板或内联声明,因此.cpp文件不起主要作用.

最近我更多地参与"传统"C++开发,面对旧的头文件/非头文件同步问题.我想知道是否有任何命令行工具可以在make目标中使用或集成到VIM来处理这个工作,即更新基于.cpp文件的头文件.基本上,类/结构或(模板和内联)实现的声明应该在头文件中忽略,而函数声明应该基于.cpp文件添加,删除或更新.

但是,我知道lzz工具要求你实际编写一个额外的第三种文件格式,然后在实际编译之前将其预处理为.h/.cpp文件.

周围有什么可以做的吗?其他非IDE开发人员如何处理这个问题?

mik*_*yra 6

由于我自己对你的第一个问题的答案非常好奇,遗憾的是我无法在这里给你任何好的建议.

至少给你第二个问题的答案:这是我用来手动添加丢失或调整不同步头文件中的更改声明的半自动方式.

使用带有警告(!)的编译器来发现缺失/更改的声明:

调整声明

更改函数定义的签名gcc后将抛出如下错误:

  • error: conflicting types for ‘....’
    note: previous declaration of ‘....’ was here

修复这个是相对容易的,因为错误消息中已经给出了对定义的引用和相应的声明.

由于我是一个emacs用户,我不能告诉你这样做的方式vi,但我很确定有一个同样简单的方法来自动跳转到这个位置.所有必须做的是:

  • 跳到位置一行复制

  • 跳转到位置2用副本替换旧行并添加尾随 ;

缺少声明

如果在另一个上添加了一个新函数而没有将它的原型添加到相应的头文件中gcc会抛出类似的东西:

  • warning: implicit declaration of function ...

修复这个标签表就派上用场了.我再也不知道如何处理它vi,但我很确定有一些方法可以快速跳转到编译器警告中其名称给出的函数定义.

这里的工作流程如下所示:

  • 跳转到函数....的定义,复制线

  • 切换到头文件,粘贴行并添加尾随 ;

虽然这种方法不过是优雅的,但它已经证明适用于我忘记调整标题以使其与源文件保持同步的情况,这可以通过几次击键来完成.

一个破碎的例子

为了通过示例在这里演示它的应用程序,需要修复标题的最小程序:

/* main.c */
#include "add.h"

int main (int argc, char *argv[]) {
  int a=0, b=0;

  add (a, b);
  sub (a, b);

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

这两个函数addsub定义在add.c如下所示:

/* add.c */
#include "add.h"

int add (int a, int b) {
  return a + b;
}

int sub (int a, int b) {
  return a - b;
}
Run Code Online (Sandbox Code Playgroud)

罪魁祸首add.h显示函数的签名不匹配和函数add的缺失声明sub:

/* add.h */
long add (long a, long b);
Run Code Online (Sandbox Code Playgroud)

尝试编译将导致:

gcc -Wall main.c add.c
main.c: In function ‘main’:
main.c:7: warning: implicit declaration of function ‘sub’
add.c:3: error: conflicting types for ‘add’
add.h:2: note: previous declaration of ‘add’ was here
Run Code Online (Sandbox Code Playgroud)

修复示例

缺少声明

第一个问题:

  • main.c:7: warning: implicit declaration of function ‘sub’

是由于sub缺少声明的事实add.h

找到合适的签名:

  • C-x` (next-error)将跳转到错误的位置
  • M-. (gtags-find-tag)将提示标签进行查找
  • RET将跳转到定义,sub因为点上的符号是默认值
  • M-z{(zap-to-char)C-y(yank)复制签名

到目前为止,所有步骤也可以由键盘宏自动完成,因为不需要干预.下一部分必须手工完成:

  • 打开"正确"的头文件
  • 并导航到应该输入声明的位置

由于选择"正确"的头文件和"正确"的位置很可能是一个品味的问题,与目前采取的步骤形成对比,我认为这里没有太多的自动化.

最后,最后一步是粘贴复制的签名:

  • C-yM-y 粘贴复制的签名
  • DEL;替换{;

调整声明

接下来add必须修复s声明和定义之间的不匹配.

add.c:3: error: conflicting types for ‘add’
add.h:2: note: previous declaration of ‘add’ was here
Run Code Online (Sandbox Code Playgroud)

要从定义中复制新签名:

  • C-x` (next-error)将跳转到定义的位置
  • M-z{(zap-to-char)C-y(yank)复制签名

要取代声明:

  • C-x` (next-error)将跳转到声明的位置
  • M-z; (zap-to-char)删除旧的声明
  • C-yM-y 现在粘贴复制的签名
  • DEL;替换{;

又回来了

由于已经有两个缓冲区:

  • M-2M-x burry-buffer 应该回到以前访问过的缓冲区

摘要

正如您所看到的那样,虽然不是太耗时的过程不断地来回使用这种方法来修复缺失或错误的声明仍然是一项相当繁琐的任务我只使用它来修复我在第一次运行中输入错误或完全错过的声明.

手动将"正确"声明放入标题仍然是我采取的主要方法.

在实施之前布置API可能不是最糟糕的想法恕我直言,这个策略不应该是一个太糟糕的选择.


Mad*_*ist 1

在 UNIX 类型的系统上,IDE 通常不处理这项工作(根据我的经验)。构建工具(通常不与 Eclipse、Emacs 等 IDE 捆绑在一起)将完成这项工作。

在现代系统中,处理这个问题的最佳方法是让编译器来做:毕竟,编译器最了解。GCC 和大多数其他 UNIX/POSIX 编译器都具有在源文件编译期间发出 make 样式依赖项声明的选项。您只需在 makefile 中进行安排,然后将输出文件包含在 makefile 中,一切都运行良好。

例如,请参见: http: //make.mad-scientist.net/autodep.html

然后检查 GCC 选项,例如-MMD -MP(这些是预处理器选项)。

  • 我不确定我是否正确理解你的答案。我不想自动生成我的 make 目标,我想自动生成我的 .h 文件本身。 (9认同)
  • 那是我的错误。我总是想象 IDE 人们有“添加新成员变量”或“添加新成员函数”等按钮。为了更改函数签名,我希望 IDE 能够提供重构工具,但如果 IDE 也要求用户更改两个文件中的签名多余,那么显然没有人对此感到不安?我很惊讶... (8认同)