I am currently implementing NASM-like preprocessor for my assembler, and I am wondering what is the correct way of handling recursively included files. From what I see, there are two ways to deal with it without hanging the preprocessor or even the OS:

Set maximum include depth.

Disallow including a file recursively (not to be confused with disallowing including a file twice).

Also, as far as I can see, the second approach does essentially the same job, but produces nicer error messages. Compare output of Clang, when compiling file containing #include "main.cpp" only:

In file included from main.cpp:1:
[ repeated many times ]
In file included from main.cpp:1:
main.cpp:1:10: error: #include nested too deeply
#include "main.cpp"

with this (current way of handling this in my preprocessor; input is similar to above, does %include "1.mov.asm" at line 6):

In file /home/griwes/projects/reaverasm/tests/1.mov.asm in line 6:
Error: file `/home/griwes/projects/reaverasm/tests/1.mov.asm` included recursively.

Nice question. I immediately fired up my IDE (Delphi2007) to see what that does. It detects the recursion on compile (error) but it still hangs if I open one of the recurring files (takes full CPU on one core) with memory increasing.
–
Jan DoggenMar 9 '13 at 19:04

2 Answers
2

The Boost.Preprocessor library extends and abuses the C/C++ preprocessor in strange and wonderful ways. One of its features is file iteration, which lets you #include a file multiple times with different macros #define'd each time, and they note that it can be useful (and is supported) for a file to iterate over itself. (Search the examples here for BOOST_PP_IS_ITERATING.) This is an example of (limited) recursion.

I have seen multiple real-world examples where recursive inclusion was desired, but it was usually to work around limitations in the preprocessor. I feel it is wrong to disallow any recursion but a limit of 10 times is reasonable IMO.

Well, those two things are quite close to each other; depending on how you handle the recursive inclusion, you either get one error output or another. Also, could you provide some of those examples when recursive inclusion was desired?
–
GriwesMar 9 '13 at 17:30