Porting from Visual C++ 6.0 to Visual Studio Tricks and Tips?

Started by
7 comments, last by jbadams 10 years, 11 months ago

I've been quite happily using Visual C++ 6.0 for years for my own personal game development and have never until now felt the need to upgrade to any version of Visual Studio (basically, if it isn’t broken and it is still performing well then why try to fix it).

(Un)fortunately the time to change has come with a change of computers and a move from XP to Windows 8 ... Visual C++ 6.0 just about works in Windows 8 but having played a little with Visual Studio 12 I am beginning to see the advantages of a move. Unfortunately my existing code base (30,000+ lines of code) is reluctant about the move ... I have updated the project, sorted out all kinds of compilation errors, but when running my compiled code I consistently get crashes. Debugging seems to point to problems with my use of std::map and std::list code, although to be honest there is more than a hint that there may be a problem with dynamic memory / pointer use.

This is all a little bit frustrating as the code still compiles and runs successfully in Visual C++ 6.0 (even on the new machine), I now have to look through the 30,000+ lines of code when normally debugging is limited to the most recent code additions, and I suspect that I have got into bad / non-standard, but successful habits in the past so something that is obviously wrong to someone more familiar to Visual Studio will look right to me!

To help me with this process are there any good sources (websites, whatever) that highlight commonly needed code changes for people porting from Visual C++ 6.0 to Visual Studio and/or updating std::map and std::list code ... or will I just have to break down my code base, debug and rebuild bit by bit (which will probably take ages as some of the code has been left untouched for years).

Jon.
_______________________________________
Legends from the Lost Realms
Advertisement

How about just reading official standards compliant documentation on the use of std::map and std::list? The latest version (edition 4) of The C++ Programming Language is due out in the middle of May so get that and see what the differences are between your code and the C++ standard. Plus it'll get you up to speed with more modern C++ usage and abilities that you are probably unaware of.

VC6 was certainly a good compiler for its time, no disputing that. The programs still run and things will mostly work okay.

But that was from 1998.

The compiler pre-dates the original C++ standard. In fact, it was rushed at the last minute so that it could be released before the C++98 standard was finished. It took four years for them to modify the compiler enough to handle the C++ standard. They managed to get the compiler out just a few months before the second edition of the standard was released.

I suspect that I have got into bad / non-standard, but successful habits in the past

You have been learning pre-standard C++. The language is dramatically different.

There have been four revisions of the standard since VC6 came out. First was the original standard, C++98. Then there was C++03. In 2007 there was an update nicknamed C++TR1. Finally there was the C++11 update.

Memory allocation is dramatically different than what you know in VC6, and all for the better. The VC6 containers needed strong modification to fit in the standard. I don't know if any smart pointers existed back in VC6, but for modern code you better learn about them.

There was a very good reason that many businesses took the opportunity to rebuild their apps from the ground up around that time frame. The post-standard tools broke the pre-standard code so badly that it was often easier to rewrite rather than debug and fix.

To narrow down your errors, you could try some static code analysis tools. If you have a fat wallet, I've heard some decent things about PVS Studio. If you are on more of a budget, then VS2012 (not sure about express) has some integrated static analysis, and there's a few other options if you search around the Internet.

Aside from mostly corner cases (and the infamous for loop scope), my experience is that it mostly trivial to make VC6 code build on newer versions of visual studio.

Do you have any examples of something that crashes?

Thanks for all the feedback so far ... much appreciated.

There was a very good reason that many businesses took the opportunity to rebuild their apps from the ground up around that time frame. The post-standard tools broke the pre-standard code so badly that it was often easier to rewrite rather than debug and fix.

This is what I'm worried about! Ideally I would like to avoid several weeks/months of debugging or recoding to bring this up to date (especially with Visual C++ 6.0 looking over my shoulder and saying "I still work!"). Anyway the process has started and I am unit testing and analysing each class ... good thing I'm not running to a deadline.

To narrow down your errors, you could try some static code analysis tools. If you have a fat wallet, I've heard some decent things about PVS Studio. If you are on more of a budget, then VS2012 (not sure about express) has some integrated static analysis, and there's a few other options if you search around the Internet.

I'm already using the VS2012 static code analysis (it is available in the Express version) and this is actually one of the main attractions of moving up as it is very useful in tracking down the stupid errors that usually take ages to find.

Do you have any examples of something that crashes?

Not any more ... or at least not worth sharing at this point. I have a list of changes to check through in all my code and I have unit tested one of each of my std::list and std::map using classes and they seem to be clean and consistent with the current standards ... and they compile and run without any problems on their own. Still looking for the source of the crashes but am now doing this systematically by cleaning up the whole code base rather than just trying to fix the immediate problem. Will provide an update or examples when the current clean up is completed.

Jon.
_______________________________________
Legends from the Lost Realms

You probably have functionality in your codebase that is dependent on "undefined behavior", and the behavior of the compiled code is different between the two compilers. This is similar to what happens when something in works in debug but not in release.

Also are you doing anything with your own non-STL templates? because templates used to be really broken in VC++6 as I recall, but this was more about casuing compile time errors.

As for what to do about it,

  1. Make a pass through your codebase adding asserts where appropriate and see if you can find asserts that fail.
  2. If you have sufficiently modular design, write unit tests for various modules and see if you can get a unit test to succeed under VC++6 and fail under VS2012.
  3. Otherwise, try to get a minimal version of the application working without exhibiting crashes, and then re-introduce pieces of functionality one-at-a-time until you see a crash.

Finally, after many days of testing I have made the migration to VS2012 .. phew!! I won't go into all the details, but to highlight a few things that helped a lot in the process,

  • I actually updated the code in VC++ 6 rather than in VS2012. To explain I went back to the original code base and tried to compile it in VS2012, recorded all the compilation errors and corrected them in VC++ 6. This allowed me to make small step changes and check that each change worked before moving on to the next. Meant a lot of swapping between compilers but avoided blindly correcting loads of errors and only being able to test when all errors had been corrected (basically if the code stopped working in VC++ 6 I would only have a few changes to debug).
  • A lot of the effort was involved in tidying up the istream and ofstream handling - the standard really has changed from what I could get away with in VC++ 6 (even if, as it turned out, I could bring my code up to the standards in VC++ 6)
  • NULL is no longer my friend ... there were a lot of instances where NULL checking had to be updated to make proper use of defined boundary checking functions.
  • The static code analysis has been useful for cleaning up some untidy code and making things even safer, but it (obviously) doesn't spot everything and I had one memory overflow that somehow worked in VC++ 6 but choked VS2012 (as mentioned by jwezorek)
  • In the end it was chasing down the broken class, isolating it from the rest of the code and testing and testing again until the bugs were found.

Many thanks for all the feedback - it really helped.

Jon.
_______________________________________
Legends from the Lost Realms
Thanks for coming back to share your experience Jon!

- Jason Astle-Adams

This topic is closed to new replies.

Advertisement