How can I automatically generate / update header files from cpp files without using an IDE?

As I myself am very curious about answers to your first question unfortunately I am not able to give you any good advice here.

To at least give you an answer to your second question: This is the somewhat semi-automatic way I use to manually add missing or adjust changed declarations in out of sync header files.

use the compiler with warnings enabled (!) to spot missing / changed declarations:

Adjust declarations

After changing the signature of a function definition gcc will throw an error like the following one:

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

Fixing this one is relatively easy as both a reference to the definition and the corresponding declaration are already given in the error message.

As I am an emacs user I can’t tell you the way this is done in vi, but I am quite sure there is an equally simple way to automatically jump to this spots.
All that has to be done is:

  • jump to location one copy the line

  • jump to location two replace old line with the copy and add a trailing ;

Missing declarations

If on the other a new function was added without adding it’s prototype to the corresponding header file gcc will throw something like:

  • warning: implicit declaration of function ...

Fixing this one a tag table comes in handy. Again I don’t know for sure how this is handled in vi, but I am quite sure there is some way to quickly jump to the function definition given by its name in the compiler warning as well.

Workflow here looks like this:

  • jump to function ….’s definition, copy line

  • switch to header file, paste line and add a trailing ;

While this method is anything but elegant it has turned out to be working for those cases in which I forgot to adjust the header to keep it in sync with the source file, which can be done with a few keystrokes.

A broken Example

To demonstrate its application by example here a minmal program that needs it’s headers to be fixed:

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

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

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

  return 0;
}

Both functions add and sub are defined in add.c shown below:

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

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

int sub (int a, int b) {
  return a - b;
}

The culprit add.h shows both a signature mismatch of the function add and a missing declaration of the function sub:

/* add.h */
long add (long a, long b);

Trying to compile will result in:

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

Fixing the example

Missing declarations

The first problem:

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

Is due to the fact that a declaration of sub is missing in add.h

Finding the right signature:

  • C-x` (next-error) will jump to the location of the error
  • M-. (gtags-find-tag) will prompt for the tag to lookup
  • RET will jump to the definition of sub as the symbol at point is the default
  • M-z{ (zap-to-char) C-y (yank) to copy the signature

Up to here all steps could have also be done automatically by a keyboard macro as no intervention was needed. The next part will have to be done by hand:

  • open the “correct” header file
  • and navigate to the spot where the declaration should be entered

As the choice of “correct” header file and “correct” location most probably is a matter of taste in contrast to the steps taken so far I don’t think there’s much automation possible here.

Finally the last step is to paste the copied signature:

  • C-yM-y paste the copied signature
  • DEL; to replace { with ;

Adjusting declarations

Next the mismatch between adds declaration and definition has to be fixed.

add.c:3: error: conflicting types for ‘add’
add.h:2: note: previous declaration of ‘add’ was here

To copy the new signature from the definition:

  • C-x` (next-error) will jump to the location of the definition
  • M-z{ (zap-to-char) C-y (yank) to copy the signature

To replace the declaration:

  • C-x` (next-error) will jump to the location of the declaration
  • M-z; (zap-to-char) to delete the old declaration
  • C-yM-y now paste the copied signature
  • DEL; to replace { with ;

And back again

Since two buffers have been poped:

  • M-2M-x burry-buffer should go back to buffer that was visited before

Summary

As you can see while not a too time consuming process constantly jumping back and forth to fix missing or wrong declarations using this approach is still a rather tedious task I only use it to fix up declarations that I mistyped or completely missed in the first run.

Manually placing the “correct” declarations into the header still is the main approach that I take.

As laying out the API prior to implementing it might not be the worst idea IMHO this strategy shouldn’t be a choice too bad.

Leave a Comment