0

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.

The purpose is NOT to detect plagiarism, as some tools I've found do. The purpose is to automatically detect whether a cosmetic change to the source code is really purely cosmetic, i.e. whether it changes something other than formatting, comments or variable names (or other identifiers). Obviously a regular text diff tool can't efficiently help here; this needs a language-specific tool.

Preferably, 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'm not asking for these kinds of changes to be automatically detected and ignored by the tool; it would be cool but it's not a requisite.

One possibility I have thought of, is to use a source minifier and compare the minified versions, but I haven't found a C++ minifier that is also able to deal with local identifiers.

  • There is no definition of cosmetic changes in your question, and in practice most source code changes are not cosmetic (think of a small change inside a template definition or inside an inlined method) – Basile Starynkevitch Oct 10 at 11:57
  • And what should happen for cosmetic changes inside template-s or inside #defined macros? Your definition is not algorithmic. – Basile Starynkevitch Oct 10 at 12:07
  • You could use plagerism detectors and you might find one for C++. But that was not your question at all – Basile Starynkevitch Oct 10 at 12:20
  • And __LINE__ is often preprocessor-expanded into different things for different occurrences, soI still don't understand your question. What about for (i=__LINE__%4; i<100; i++) which does make sense (and could be used inside another macro; I have good scenarii for that code)? – Basile Starynkevitch Oct 10 at 12:21
  • @BasileStarynkevitch in your answer and throughout your comments, you keep missing this point: I'm not after a "perfect" tool that is able to discern whether two programs are equivalent, but JUST a tool that filters out some of the most common cosmetic changes in order to make it easier to identify if there are non-cosmetic changes. I expect that some changes will need manual evaluation, and I'm OK with that. I don't care if the program can't catch __LINE__ calls or whatever because, again, I expect manual intervention to be necessary in some cases. I want an aid, not a full automation. – Pedro Gimeno Oct 10 at 13:59
1

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 basile.starynkevitch@cea.fr; thanks.

  • You're reading too much into my question. I'm aware that detecting semantic differences is hard, but that's not what I'm asking. Please read carefully the first paragraph you've quoted. Note that I ask if they are the same, not if they are equivalent. A program that performs preprocessing, reformats the code, renames all variables to unique sequential names and compares the resulting text, would fulfil the requisites, and it'd be relatively simple. Comparing binaries WITHOUT optimization would also do that to some degree, but if there are changes, it's impractical to find where they are. – Pedro Gimeno Oct 10 at 11:11
  • Your cosmetic change involves scoping. I don't call that "cosmetic" (and for could have been the result of a macro-expansion by some #defined C++ macro) – Basile Starynkevitch Oct 10 at 11:31
  • The for example was an example of a difference that I expected the program to find. I say that it would be nice if it could ignore such differences, but it was not a requisite. – Pedro Gimeno Oct 10 at 11:38
  • I recommend starting a PhD on comparative static source code analysis of C++ programs. Your problem is an excellent PhD subject (and I or some colleagues of mine might be your advisor). Maybe there is a funding opportunity in the lab I am working in (I don't know but could transmit your questions) – Basile Starynkevitch Oct 10 at 11:42
  • And Rice's theorem still holds. – Basile Starynkevitch Oct 10 at 11:50
0

I don’t think that you will get a better open source application than WinMerge (although it would do no harm to look at Kdiff3.

Neither of them will handle your int i; for (i ...) -> for (int i ...) example, but they are open source, so you might give it a try, or request the feature from the author.

enter image description here

General
• Supports Microsoft Windows XP or newer
• Handles Windows, Unix and Mac text file formats
• Unicode support
• Tabbed interface

File Compare
• 3-way File Comparison New!
• Visual differencing and merging of text files
• Flexible editor with syntax highlighting, line numbers and word-wrap
• Highlights differences inside lines <= ============================================
• Difference pane shows current difference in two vertical panes
• Location pane shows map of files compared
• Moved lines detection

Folder Compare
• Regular Expression based file filters allow excluding and including items
• Fast compare using file sizes and dates
• Compares one folder or includes all subfolders
• Can show folder compare results in a tree-style view
• 3-way Folder Comparison Work in progress

Image Compare New!
• Support many types of images
• Can highlight the differences with blocks
• Overlaying of the pictures is possible
Version Control
• Creates patch files (Normal-, Context- and Unified formats)
• Resolve conflict files

Other
• Shell Integration (supports 64-bit Windows versions)
• Archive file support using 7-Zip
• Plugin support
• Localizable interface
• Online manual and installed HTML Help manual

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.