(This might affect the C front end also, I have not tried). Basically, there are situations where g++ -E accepts multi-line string literals and glues them together into a proper string literal token. If the resulting preprocessor output is compiled, there are no diagnostics. But if the compiler is run on the original code, there are diagnostics. Test case:
#include <cstdio> #define pf(FMT, ARGS ...) printf(FMT, ## ARGS) int main() { pf("Hello, %s!", "world"); } If this is passed through g++ (4.3.2) there are warnings from the preprocessor about unmatched " characters. But the problem is repaired in the output, where the pf expression turns to: printf("Hello, %s", "world"); The preprocessor output, if captured, can be compiled without diagnostics, because it no longer contains a multi-line string literal. If the program is compiled directly, there are syntax errors from the compiler, in addition to the warnings from the preprocessor. The behavior of the preprocessor, when integrated into the compiler, is different; it does not repair the broken string literal. In g++ 4.1.1, the behavior is similar, except that preprocessing does not emit any diagnostics at all in either situation, so if the compilation is broken into two steps (preprocess with g++ -E and then compile), then it's completely silent. To answer the question, why would anyone preprocess and then compile: there are tools which do this, like ccache. The ccache program preprocesses a translation unit, and digests it to a hash. Using the hash, it can decide to retrieve a cached object file, or to pass the preprocessed output to the compiler (avoiding double preprocessing). Other tools like distmake and distcc works similarly. So when ccache is used with g++, in effect the combo turns into a C++ implementation that accepts broken string literals when they are macro arguments. If developer accidentally write such string literals, then the build breaks for anyone who runs it without ccache. (If there is a way for to run g++ or gcc as a preprocessor in such a way that it does not accept multi-line string literals as macro arguments, please advise; I can hack it into ccache as a workaround). -- Summary: preprocessing different in g++ -E and regular compiling. Product: gcc Version: 4.3.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: kkylheku at gmail dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38990