Refactoring browsers for C and C++

This is a discussion on Refactoring browsers for C and C++ within the Tech Board forums, part of the Community Boards category; Recently, while searching for a tool to automatically rename variables, I came across the technique of refactoring , in particular ...

Refactoring browsers for C and C++

Recently, while searching for a tool to automatically rename variables, I came across the technique of refactoring, in particular refactoring browsers (which let you refactor code from within an IDE).

However, I can't seem to actually find a free refactoring browser for C and/or C++. Refactoring C++ seems to be quite difficult, at least compared to Java, which has many refactoring browsers. Martin Fowler's list of refactoring tools which have passed his "refactoring rubicon" has lots of Java tools, but there are only three C/C++ ones: SlickEdit, Ref++, and Xrefactory, none of which seem to be any good. I'll give SlickEdit a try once I have a faster internet connection, but Ref++ doesn't appeal to me because I use Dev-C++ or Code::Blocks if I have to develop under Windows, and Xrefactory is a trial program only (you can run it for 8 days) -- besides, I don't understand Emacs.

So I was wondering what other refactoring browsers for C and C++ are out there, preferably free ones that run under Windows and Linux -- but any information would be nice.

"Simplicity does not precede complexity, but follows it." -- Alan Perlis
"Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
"The only real mistake is the one from which we learn nothing." -- John Powell

The problem is that C++ is so terribly hard to parse. There's not a single general-purpose, complete, free C++ parser out there. The only complete and free parser is the one in GCC's C++ compiler, and that one is extremely specialized.

There's also the problem of incomplete information - sure, you can rename a method, but how many templates rely on a method of that name?

From what I understand Eclipse is available as a free editor, and has refactoring as part of it - although I'm not sure if the refactoring is part of the free version. [Where I work, we use a derivative of Eclipse, and it has a "refector" menuitem on the "context sensitive" menu - I've never explored it, as I've not yet needed to use that functionality].

It appears that you are right - not that I would have thought differently. Apparently, the "refactor" menu only supports renaming of classes, and as I said, this is a derivative of Eclipse, so it has some extensions that are not part of regular Eclipse.

Yes, I'm aware of how difficult C++ is to parse. I didn't think there would be any C++ refactoring browsers out there, but I did think that perhaps there would be a C one.

I found a project called cpptool, which is an attempt to create an open-source (MPL) C++ refactoring tool. It's not a very large project, and it was last updated a few years ago (2003 or 2004), but maybe it's something at least. In the resources/ subdirectory of the source code, it has a "distilled" version of g++'s BNF parser, though I'm not sure if it uses it or not.

I couldn't get cpptool (or rfta) to compile with g++; it seems to require MSVC. (All those missing typenames . . . .) I'll see what happens once I install MSVC. On the other hand, I may have downloaded an older version of it. The .RAR file is half the size of the .ZIP file, which I thought was an unusually good compression ratio.

I did try Eclipse's refactoring features, and discovered exactly the same thing: it only works for Java, and the refactorings are pretty limited in any case. ("Move" and "Rename" a file, as far as I can see. This, being Java, involves renaming any classes in the files, of course.)

"Simplicity does not precede complexity, but follows it." -- Alan Perlis
"Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
"The only real mistake is the one from which we learn nothing." -- John Powell

Well, I would really like a refactoring program. Since there don't seem to be any around, how difficult would it be to create one? I'd like to make a simple C refactoring program -- I think a C++ one would be a bit too complex.

It must be more difficult than I imagine to do C refactoring, because of the very fact that there aren't any programs that do it.

Would it be possible to use an existing C parser like GCC to create a parse tree of sorts to manipulate? Besides the fact that GCC is overwhelmingly complicated, I don't know how easy it would be to re-create source code from a parse tree. Probably next to impossible.

"Simplicity does not precede complexity, but follows it." -- Alan Perlis
"Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
"The only real mistake is the one from which we learn nothing." -- John Powell

Seriously, I worked for a company that wrote a "struct parser" for a particular project. It was not easy - it didn't have to deal with anything other than reading structs and unions, but it still got pretty complicated and there were loads of strange bugs to sort out.

I doubt that the parser in gcc is particularly easy to take over for a different use - there is probably other code available that can do that "better and easier" - although I haven't looked.

The preprocessor shouldn't really be a big deal - since you can always cheat and use the preprocessor itself to sort that [although it may be slightly difficult to re-assemble the ouptut of the cpp back into C/C++].

Seriously, I worked for a company that wrote a "struct parser" for a particular project. It was not easy - it didn't have to deal with anything other than reading structs and unions, but it still got pretty complicated and there were loads of strange bugs to sort out.

It would be complicated, I'm sure, but in C at least function names always refer to the same but of code (unless they're static -- but then you just look at the one file), unlike in C++. (Is it a global function? A member function of the class? A member function of the base class? Is it this overloaded version or that one?)

Of course, a program that did this would have to be carefully written so that it could be extended in the future, or else you end up with a bunch of programs that all do one little refactoring and a whole mess of code . . .

I doubt that the parser in gcc is particularly easy to take over for a different use - there is probably other code available that can do that "better and easier" - although I haven't looked.

I think you're probably right.

Have you ever looked at Doxygen? Would it be of any use for this sort of thing?

The preprocessor shouldn't really be a big deal - since you can always cheat and use the preprocessor itself to sort that [although it may be slightly difficult to re-assemble the ouptut of the cpp back into C/C++].

"Simplicity does not precede complexity, but follows it." -- Alan Perlis
"Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
"The only real mistake is the one from which we learn nothing." -- John Powell

Off the top of my head, I'd say simple renamings in C can't be too hard, provided that you're willing to accept errors introduced by weird preprocessor usage. Compared to C++, C is very easy to parse.
What you really need is a good name/scope tree that you can fill with input from multiple files.

If you need a preprocessor whose output you can actually use, consider Boost.Wave.

I would have thought that even in C, one of the major points would be to rename structures and other datatypes, but yes, I agree with the principle.

Probably so, but it's not something I find myself doing quite as often. Also, I always name my structure tags with an _t suffix, so search-and-replace is reasonably simple when I rename them. [edit=2] Structure members are a different matter, of course. [/edit]

Consider also: local variables that overlap globals, so like CornedBee says, you have to track the scope.

Yes, and you also have to handle stuff like

Code:

int x;
{
int x;
{
int x;
}
}

so scoping would be essential. [/edit]

What you really need is a good name/scope tree that you can fill with input from multiple files.

Exactly! Any ideas?

Would it be that difficult to generate C code from a tree like that? Probably not . . . different styles would be another matter, but I'd leave that to indent.

Off the top of my head, I'd say simple renamings in C can't be too hard, provided that you're willing to accept errors introduced by weird preprocessor usage.

That's what I had thought.

Modularizing code (I think Fowler likes to call it "Method extraction") would be more useful, but certainly a lot more complicated. You'd have to look at what local variables a block of code uses, and if the code modifies more than one value, figure out how to return that to the calling function. With pointers, each variable would have to be modified.

On the other hand, it could be done only knowing the code for one function, because you're introducing new code, not modifying existing code.

Compared to C++, C is very easy to parse.

Yes, indeed.

If you need a preprocessor whose output you can actually use, consider Boost.Wave.

Boost.Wave does look interesting. I might consider it if I want to do preprocessing stuff -- though I usually use C instead of C++, for no particular reason. The Boost.Wave icon drives me nuts for some reason. It doesn't "move" often enough.

"Simplicity does not precede complexity, but follows it." -- Alan Perlis
"Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
"The only real mistake is the one from which we learn nothing." -- John Powell

eclipse/cdt knows also refactoring for c/c++. But the only supported operation for now is rename. it works quite well most of the time.
According to Doug Schaefer, cdt-developer, other operations should follow in near future, IIRC after he got the eclipse file system to work.

If you are willing to spend some money get visual assist for VS. it has a ........ing lot of refactoring functions implemented.

"Simplicity does not precede complexity, but follows it." -- Alan Perlis
"Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
"The only real mistake is the one from which we learn nothing." -- John Powell