C Programming: Preprocessor, include files from ma

2020-04-20 21:39发布

问题:

If I could find a way to do something similar to this, I could cut out hundreds of lines of code in my application, and dramatically increase maintainability. Anyone have any ideas?

#include <stdio.h>

int main( )
{
  #define include_all_files(root)   \
            #include #root "1.h"    \
            #include #root "2.h"    \
            #include #root "3.h"    \
            #include #root "4.h"

  include_all_files( first_library )
  include_all_files( second_library )
  include_all_files( third_library )

  return 0;
}

EDIT:

I appreciate the responses, my example seems to be causing a misdirection in effort, so here is the problem I am actually trying to solve:

I am implementing a finite state machine. Through naming conventions, I have gotten it to be as simple to add a state as:

  STATE(initial_screen)
    #include "initial_screen.state"
  END_STATE

  STATE(login)
    #include "login.state"
  END_STATE

However, if I could answer the original question, I could refactor this down to something as simple as:

  ADD_STATE(initial_screen)
  ADD_STATE(login)

This is because the file name and the state name, and all the underlying wiring and everything else all follow similar conventions. However, I cannot figure out how to implement the include file based on the token received in a macro.

回答1:

Unfortunately, this is beyond the capabilities of the C preprocessor.

Have you considered using something like m4 instead?



回答2:

Why not just create a header file that itself #includes all of the other header files for the library? Then for each library you'd just include that library's one meta-header.



回答3:

To solve your clarified problem, you could just refactor initial_screen.state and login.state so that they start with STATE() and end with END_STATE. Then you can just do:

#include "initial_screen.state"
#include "login.state"

...which is equivalent to what you're after - it's just an #include instead of an ADD_STATE.



回答4:

In file includes.h

#include "1.h"
#include "2.h"
#include "3.h"

In all other files

#include "includes.h"


回答5:

The #include pre-process directive being itself handled at in the same step as the macro evaluation, this would likely not work. I don't believe the pre-processing can be recursive. (or iterative, for that matter).

Instead, the typical way this is done is to create a small include file which includes all the desired #includes. See Cory Petosky's reponse for an illustration.

A word of caution:
While this may cut hundreds of line of code, you should consider that these are "easy" lines of code. One typically skims over them, unlike lines of codes associated with the true logic of the program.

Furthermore, explicitly listing the individual includes necessary for a given file provide a bit of self documentation, and make it easier for refactoring the code when needed.

Edit: This just in ;-)
Someone just asked this SO question Good idea to put all project headers into one file?, and the responses seem to generally agree with my take that there's typically little gain to be had from grouping headers.