This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/38990] New: preprocessing different in g++ -E and regular compiling.


(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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]