C based toolchains are just broken.
There are two scenarios: in one you want to prevent a file from being read multiple times because it wastes resources (and in some sad cases, might cause issues with redefinition). In this case, you use the include guards and the compiler can do a trick to optimize out unneeded scanning.
You have this other hypothetical scenario in which you purposefully want a file to be read multiple times, with a different outcome (this kind of trickery isn't usually possible at all in other languages with module system so it is funny to argue about C being broken). Now I don't think this is a common scenario or even a good one to be in, but it is possible. The solution is simple: don't try to prevent the file from being read multiple times. Why would you try to prevent it, if it is meant to be read multiple times?
You are arguing that a door is broken because you cannot walk in through it if you close the door. Don't close the door if you want to walk in...
With the single possible exception of a file that changes on disk between the multiple includes in the same build step. That is not a situation I have ever encountered and I am not at all sure it is supported and there aren't a bazillion other things that would break it in any given compiler chain (certainly at least line directives would be wrong, but that's arguably minor I guess).
This preprocessor optimization is only for the case where include guards block off the entire #include file. Ex:
#ifndef INCLUDE_FOO_H
#define INCLUDE_FOO_H
#endif
When the preprocessor sees that, it marks it off and never reads the file again (Unless you were to #undef INCLUDE_FOO_H, but that's an extremely unlikely scenario since it's likely to break your code). If you want to be able to include a file multiple times, just don't use include guards. Even without this optimization your idea still wouldn't work if you placed include guards in your #include file. All this does is speed up preprocessing when we already know that the file has no new lines to be added.It is not a very clean way of coding, but there are many enterprise developers that provide files without include guards and include them multiple times.
An example would be generic data structures in C done with macros.
#define DATA_TYPE int
#define DATA_NAME intList_t
#include <list.h>
typedef struct { /* ... */ } Node;
#define DATA_TYPE Node
#define DATA_NAME nodeList_t
#include <list.h>In no case does this optimization change the code emitted.
http://gcc.gnu.org/onlinedocs/cpp/Once-Only-Headers.html#Onc...
This construct is commonly known as a wrapper #ifndef. When the header is included again, the conditional will be false, because FILE_FOO_SEEN is defined. The preprocessor will skip over the entire contents of the file, and the compiler will not see it twice.
CPP optimizes even further. It remembers when a header file has a wrapper ‘#ifndef’. If a subsequent ‘#include’ specifies that header, and the macro in the ‘#ifndef’ is still defined, it does not bother to rescan the file at all.