Question

I wish there was a way to split a #include directive across two lines, so that my code can conform to 80 characters per line, despite the necessity of a very long include path.

Other than expanding the search path of the compiler, how can I manage this? Is there a way to split my very long path string into two lines?

"#define" macro expansion apparently happens after #include expansion, so these don't work:

#define BIGPATH "..."
#include BIGPATH ## "/foo.c"
#include "BIGPATH/foo.c"
#include BIGPATH"/foo.c"

I've also tried

#include "foo" ##
         "bar"

and

#include "foo" \
         "bar"

To no avail. Perhaps what I want is impossible? Help me, stackoverflow kenobi, you're my only hope.

ANSWER: building on the suggested answer below, here's what actually worked for me:

#define STRINGIFY(x) #x
#define PATH(path) STRINGIFY(/my/very/long/path)
#include PATH(foo.h)
#undef PATH
#undef STRINGIFY
Was it helpful?

Solution

I do not like the idea of this, I just wanted to mention this possibility. The best is to go the way Daniel Fischer mentioned. This solution is a bit quirky and will not work under all circumstances but this compiled here:

#define PATH(FILE) </path/to/FILE>
#include PATH(file.h)

And just to name some of the obvious limitations:

  • the search path of these includes is not "local"
  • FILE must not contain "," (rather uncommon)
  • the PATH define can still exceed 80 characters

Feel free to add to this list.

Edit
Just for better readability I will post the solution from Jonathans comment below in the style of my example:

#define STRINGIFY(x) #x 
#define PATH(FILE) STRINGIFY(/path/to/FILE) 
#include PATH(foo.h)

This version mitigates the "locality problem" of the #include <> version, as it maps to #include ""

OTHER TIPS

This compiles for me (I'm basing it off of how I recall Boost.PP working):

#define a() <vec\
tor>

#include a()

int main() {
  std::vector<int> x;
}

Just change <vector> to your full path - I don't think you can concatenate strings the way you need to in #include.

Use another header file with a short name to store header files with long names. So all headers that exceed you 80 character minimum is not in you nicely formatted code.

//short_name.h
#include "really_really_long_include_name.h"

//code
#include "short_name.h"

All preprocessing directives are terminated by a new-line token. The include directive is of one of the following forms:

# include < h-char-sequence> new-line
# include " q-char-sequence" new-line
# include pp-tokens new-line

Your final example will result in the equivalent of #include "foo" "bar" being executed because, although the escaped new line deletion will occur before directive execution, string concatenation occurs afterwards. This matches the final valid form of an include directive.

However, what happens with this form is that any macro names following include will be replaced. Yours doesn't have any macros. If the resulting directive doesn't match either of the normal two forms, the behaviour is undefined.

If the directive resulting after all replacements does not match one of the two previous forms, the behavior is undefined

The standard has a specific note about the case where there are multiple string literals:

Note that adjacent string literals are not concatenated into a single string literal (see the translation phases in 2.2); thus, an expansion that results in two string literals is an invalid directive.

So that's why that example doesn't work. It does however mean that we can rely on macro expansion to generate a valid filename. For example:

#define LONG_PATH(file) <foo/bar/baz/file>
#include LONG_PATH(file.h)

Or:

#define STRINGIZE(x) #x
#define LONG_PATH(file) STRINGIZE(foo/bar/baz/file)
#include LONG_PATH(file.h)

No, you can't, the preprocessor requires the include filename to be a single preprocessing token. You need to either fix the include search path you're using, or relax the requirement of 80 characters per line.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top