I had a bad(good?) idea of further modifying C preprocessed code (call it a thought experiment.)
On my quest to achieve this I got the below sequence of shell commands. Note that I have not added any modifications to the preprocessed code, but left the ability to do so:
#!/bin/bash
gcc -E debug/*.h debug/*.c src/* > build/main.i
#Command to modify build/main.i in future
gcc -Wpointer-arith -Wall ./build/main.i -o ./bin/main.exe
However, when running the last command to compile the code, a bunch of redefinition errors are generated. An example is below. Even C-standard functions are doing the same thing.
In file included from src/String.c:3:
src/String.h:32:3: error: conflicting types for 'String'
32 | } String;
| ^~~~~~
In file included from debug/StringDebug.c:5:
debug/../src/String.h:32:3: note: previous declaration of 'String' was here
32 | } String;
| ^~~~~~
...many many more...
<path>\mingw\include\stdlib.h:916:61: error: redefinition of 'setenv'
916 | __cdecl __MINGW_NOTHROW int setenv( const char *__n, const char *__v, int __f )
| ^~~~~~
In file included from debug/../src/Object.h:4,
from debug/BasicTypeDebug.c:2:
<path>\mingw\include\stdlib.h:916:61: note: previous definition of 'setenv' was here
916 | __cdecl __MINGW_NOTHROW int setenv( const char *__n, const char *__v, int __f )
| ^~~~~~
Looking at build/main.i confirms that the same file is being included multiple times. I have header guards and don't declare any variables in my header files. I know nothing is wrong because running a normal compile command (below) works.
gcc -Wpointer-arith -Wall -o ./bin/main.exe debug/*.h debug/*.c src/*
Looking at this question, my guess as to what is happening is that the preprocessor, when called by itself, is putting the output of every single translation unit into one file, hence creating the duplicates. However, because a normal compilation command works, my guess is that the preprocessor is called once per translation unit when the compiler is invoked instead of just the preprocessor by itself.
So my question is twofold:
- Is my guess correct, or if it's not correct what is actually happening?
- If my guess is correct how do you tell gcc to output one preprocessed file per translation unit?
I understand what I'm trying to do isn't necessarily "correct", its more just to see what can be done and what can't.
EDIT
See kaylum's answers in the comments below for the answer. Not sure how I missed that looking back but hindsight is 20/20.