I'm looking for an open source tool to compare two C++ sources and tell me if they are the same after disregarding comments, formatting and identifier renames.
That could be a research project, or at least a work for a Master's degree dissertation (and probably gets you a PhD). I guess that your ill-defined problem falls into Rice's theorem so is undecidable.
Notice that your implicit dream is an automatic code reviewer. See also the DECODER project. Read more about static source code analysis, software obfuscation, abstract interpretation, operational semantics, undefined behavior, and decompilers. Read carefully the C++11 standard, e.g. n3337.
At last, the preprocessor is by itself capable of fancy things and usually used that way. Many warning or logging macros involve __FILE__
and __LINE__
or __COUNT__
(see this example and explain how would you want it -or __TIME__[0]
deeply hidden in some other macro- to be handled). Think also of x-macros, a very common practice in real C or C++ programs. Be also aware of Qt's qDebug
macro for debugging and its moc
(and explain how that should be handled). And what about C++ template
expansions (they are Turing-complete at compile-time; think of a small change inside a template
definition or inside an inlined method), so adding a single namespace
or using
or #include
line alter the semantics of the entire translation unit, notably thousands of lines below. Because of g++ -DWITHCARE=1
invocation on source code having #if WITHCARE
, the same C++ file (compiled with and without -DWITHCARE=1
; think of some Makefile
rule, or of GNU autoconf) can have very different meaning.
You could compare the machine code sections of generated .o
ELF files, after having enabled compiler optimizations.
One possibility I have thought of, is to use a source minifier and compare the minified versions,
The GCC C++ front-end (if you invoke g++
that front-end is inside cc1plus
) could be considered as a minifier. It produces GCC internal representations (such as GENERIC and GIMPLE). You might consider a GCC plugin approach and compare the GIMPLE representations. But even that is not trivial to implement.
Don't forget that C++ files could be generated (with tools like SWIG, bison, Qt moc
, simple shell scripts or Makefile
rules, or programs like my bismon or my old GCC MELT) and such generated files might be further #include
-d. And such practices are very common (e.g. the GCC compiler has dozen of generators emitting C++ code, and IIRC so does firefox
or libreoffice
).
You might consider using static source code analysis tools à la Frama-C (e.g. develop your own Frama-C plugin for Frama-C++) or build something above Clang.
In principle, my Bismon tool should be able to to what you want at end of 2020. But it is a research project (with an obligation of means not of results).
You may want to read my draft report (explaining what surprising optimizations GCC is capable of).
if the tool finds a difference, it should indicate it and then continue analysis, so that I can evaluate myself whether that constitutes a cosmetic change or not (e.g. int i; for (i
...)
-> for (int i
...)).
I strongly recommend looking with care into the source code of several existing C++ free software programs (e.g. on github or inside a Linux distribution). You'll find out how coding practices differ!
NB. The real question is: can you pay a million euros (or US$) to achieve your goals and get such a tool? (or at least 300k€). If yes, I am professionally interested, contact me at [email protected]
; thanks.
template
definition or inside an inlined method)template
-s or inside#define
d macros? Your definition is not algorithmic.__LINE__
is often preprocessor-expanded into different things for different occurrences, soI still don't understand your question. What aboutfor (i=__LINE__%4; i<100; i++)
which does make sense (and could be used inside another macro; I have good scenarii for that code)?__LINE__
calls or whatever because, again, I expect manual intervention to be necessary in some cases. I want an aid, not a full automation.