¶Visual Studio 2005 migration guide
I've been meaning to put this together for a while, but only now got around to doing so.
Here is a list of all of the issues I have run into when porting VirtualDub from Visual C++ 6.0 to Visual Studio 2005. Where possible, I have annotated the issues with links to pertinent bug reports in Microsoft Connect (some are mine). A few of these issues are due to bugs that are supposed to be fixed in the upcoming Visual Studio 2005 Service Pack 1.
When it comes to installing VS2005, expect to need about 2GB of space. I have VC++ with x64 support installed (~950MB) and most of MSDN (~800MB). I still have VC6 and VS2003 installed side-by-side with no apparent conflicts.
At this point, I've basically stopped using Visual C++ 6.0 except to maintain VirtualDub 1.6.x, as VS2005 is good enough to replace it for 1.7.x and for all the little random projects that I do on the side. Well, that, and I've become addicted to F12 (Go to Definition) and to opening files by filename (Ctrl+D, >open filename).
There are few surprises with the VC8 compiler.
All versions of Visual C++ have the optimizing compiler, including the Express edition. However, Express does not include MASM, the x64 compiler, or the Platform SDK. You can download and integrate the Platform SDK, and you can obtain a slightly older version of MASM from the DDK, which is in turn included as part of the download for the Kernel Mode Driver Framework (KMDF). Or you could just use MASM from an older version, as well.
Quite a few bugs were silently fixed, such as loop unrolling bugs, so don't be surprised if code that compiled incorrectly in VC7.1 now works under VC8. So far, I have only hit one regression in code generation correctness (100050), and I have found a number of front-end ICEs fixed. The new compiler is a bit more anal with regard to pointers to members, though, and you will get errors instructing you to change member to the compliant form &class::member. The no-aliasing switches (/Oa and /Ow) are also gone, so you may have to introduce some uses of __restrict and __declspec(noalias) to restore performance; /Oa tended to break the STL randomly, though, so you're probably better off.
One little change that can bite you is that catch(...) no longer catches Win32 exceptions, most notably access violations. In most cases this is a good thing, but you should still sweep the codebase for instances of it and switch to __try/__except as necessary.
Vectorized math code can see speedups in VC8 due to improved code generation for SSE intrinsics, as well as the semantics of the /fp:fast switch. MMX intrinsic code generation, however, is still awful. You may want to consider rewriting some critical portions of low-level libraries to take advantage of the new support for named return value optimization (NRVO), which can eliminate unnecessary copies when returning local aggregates.
The new C++/CLI syntax is a lot cleaner than the old Managed C++ syntax, and looks a lot more like standard C++. After writing some code in C++/CLI, I believe the situation has improved such that if I were forced to migrate to .NET, I would no longer have to repeatedly stab myself in the head with an icepick and only blunt trauma would suffice.
There are other little goodies added to the compiler, like support for variadic macros, and a boatload of semi-random scalar intrinsics.
The linker no longer supports emitting line-number information to map files; you will need to use DBGHELP or the DIA SDK to extract that information. What it does support, however, is directly linking in a static library by its .obj files rather than its .lib, like Fast Solution Build's multi-project incremental link. This has the potential to speed up link times, as the linker cannot incrementally link when a static library changes.
MASM and the inline assembler now enforce correct size matching for memory operands. This was actually always documented for MASM, but not enforced until now. The solution is to add memory operand size prefixes for MOVD and MOVQ instructions. If you need to keep your assembly language code backwards compatible with MASM 6.15 or MASM 7, add /DXMMWORD=QWORD to the command line.
Unlike the compiler, there are a lot of potentially problematic changes in the runtime libraries, and this is where you will have to spend a lot of time.
The first issue you will notice is a boatload of deprecation warnings for ANSI C string routines. For those of you who care at all about writing Standard C++, define _CRT_SECURE_NO_DEPRECATE and _SCL_SECURE_NO_DEPRECATE to shut up the compiler. You will still get warnings about non-ANSI C methods that are named in a non-compliant manner, like stricmp(); these should be fixed to use the underscored versions.
STL code will likely initially see a performance drop in debug builds in VC8 due to iterator checking. Define _HAS_ITERATOR_DEBUGGING=0 to disable the debug checking, once you've fixed all the broken code. Note that some iterator checks are also enabled in a Release build, and you must define _SECURE_SCL=0 to disable those; this bloats the size of normally cheap STL calls, and more importantly, can deliberately crash your program on calls that are normally incorrect but innocuous (&v on an empty vector). I recommend doing a test pass on your program and fixing all STL usage bugs that the debug CRT finds, and then flipping _SECURE_SCL=0 to avoid any nasty surprises post-ship.
Another nice bear trap that was added was code to directly invoke Watson if certain invalid parameter conditions are detected (101337). This is not a joke; the CRT will actually rip off any exception handler you may have registered using SetUnhandledExceptionFilter() and force the regular Watson-based crash dialog to appear. This is irritating for those of us who have custom crash handling code, and for some cases there is apparently no workaround other than to hook the SetUnhandledExceptionFilter() API through evil patching means (muhahaha).
Finally, the VC8 library has raised platform dependencies compared to VC6 and VC7.1: it requires functions that are not present in Windows 95 or NT4, so you will have to drop support for those unless you hack in replacements for those functions (primarily IsDebuggerPresent and GetLongPathName), or find a way to link against MSVCRT.
Dependency checking has been reworked in VS2005, so you will see major improvements in incremental build times in large solutions over VC7.1 (unless you are using FastSolutionBuild), as well as a lot less spew for projects that are up-to-date.
DEVENV has a problem with output buffering that prevents it from regularly showing progress during command-line builds (106730). Working around this problem requires using the /OUT flag and writing a program to "tail" the log file instead. You can use VCBUILD as well, but I had problems removing the extra formatting that it adds -- you can kill the output coloring, but I couldn't find a way to remove the 23> that it adds in front of warnings.
When upgrading a project from VC6 or VS2003 to VS2005, the import code will silently turn on the "compliant for loop scope" and "wchar_t as native type" options. It is good to fix your code to work with these enabled, as they improve C++ standards compliance, but you may have to temporarily turn them back off in order to get your code to compile first.
If you have any non-trivial amount of include paths or preprocessor defines that need to be added to every project, I highly recommend looking into the new project property sheet and solution macro features. These allow you to centralize cross-project settings into a small number of easily modifiable property sheets and greatly ease vcproj management. Just make sure to explicitly save them (100047).
Never change parameters for a solution configuration and then change the solution configuration to edit in the same dialog; this will scramble the second configuration's settings (114949). This bug was inherited from VS2003, btw.
You may encounter some problems with constant rebuilding when static libraries change. The manifest tool doesn't update the timestamp of its output when it doesn't actually change and this can cause one form of the problem (100053). I haven't found a fully satisfactory solution to this, but the quick fix isn't too bad: remove the build outputs for the affected projects and force a relink. You do not have to recompile. Also, if you interrupt a build at just the wrong time, the manifest tool may start crashing on subsequent build attempts. Just delete the broken EXE file to fix the problem.
Overall, if you have already migrated to VS2003, the build system should not cause you too much trouble.
The defaults are quite a bit more colorful than VS2003, especially when combined with the new change bar. The registry patch to enable column bars in VS2003 also works in VS2005.
Source code control works rather smoothly with the latest Perforce plugin. "Check-in" now consistently adds files to the pending changelist rather than actually allowing VS to check in random files. I don't know if Perforce Software or Microsoft was responsible, but all is good now. SCC background updates take a long time to complete -- the IDE checks files at about 10/second, so it can take minutes for it to completely check the solution. The background update does not noticeably affect performance or usage, though, and presumably it was slowed down to avoid bogging down the IDE.
Intellisense is better at staying in the background for C++ than in VS2003, and the text editor pauses a lot less as a result. However, it seems to have some issues dealing with the ANSI/Unicode defines in <windows.h> and will sometimes report the W versions of a function rather than the #define that you are supposed to use. Also, Intellisense can have trouble keeping up with you as you type, and it is not unusual for it to not see a class member that you have just added; save and wait for a moment for it to reparse. Since Intellisense now parses system headers, this can take a while (up to around 10 seconds for VirtualDub, which is ~4MB of source).
Code that contains conditionally enabled code for x86/x64 may cause the editor to blank out the wrong code in x64 configurations (98974). Explicitly add the symbols to the project preprocessor definitions as a workaround.
For C# code, Intellisense popups seem to take a while to appear and adds a bit of "hitchiness" to the editing experience as they cause the editor to periodically stall for fractions of a second as you type. The delays are not enough to be a major problem, but they can be a bit disconcerting.
The bugs regarding the "tabify selection" command adding tabs within string literals and single spaces has been resolved (106390), but in a goofy manner: new default commands have been added to only modify leading whitespace. The old commands are still there and are still bugged.
File type autodetection has changed a bit and you may have problems with the editor misdetecting files, as I did; you can fix this in the extension mapping page in Options, but will need to hack the registry (106395) to associate "Source Code (Text Editor)" with an extension.
No, you can't turn the gradients off, and even worse, you cannot change the font of the solution explorer, though, as it is hardwired to use the Icon font in Windows (109160). The IDE also has a habit of flickering in odd ways; for instance, hitting Find (Ctrl+F) causes the Solution Explorer to redraw.
Context menus can now be modified. I recommend adding the "Move into project" command back into the text editor popup.
Docking buttons now appear when you drag a tool window. It takes a little getting used to, but once you're over seeing a dozen buttons flash on screen, it's a much faster way to precisely drop a tool window than waving it all over the IDE and watching for the outline to appear in the right location.
The Win32 resource editor is largely unchanged (100052), so I still hate it. It hasn't munged my .rc file yet, though, which the VS2003 resource editor did several times. Note that Express does not include the Win32 resource editor, even though it includes the WinForms editor.
Mixed-mode debugging is much much much much MUCH faster. Did I mention it was much faster? Unfortunately, you can't use it to debug VS2003-built mixed-mode executables.
You could use the Microsoft symbol server in VS2003, but you had to manually add SRV*path*http://msdl.microsoft.com/download/symbols to the solution symbol path. There is now a symbol server management page in Options that makes this easier. In addition, each symbol server has a checkbox, which makes it really easy to disable auto-download and have the debugger only use the local cache -- very useful since the debugger sometimes keeps contacting the Microsoft symbol server for non-Microsoft DLLs (for me, it keeps trying to download symbols for Trillian's injected events.dll). Several of the .NET Framework DLLs which were built with UNC pathnames in their PDB reference resource were also fixed to use drive letters in the 2.0 Framework, fixing another source of network lookups from the debugger -- just make sure F: is not a network drive!
Call stacks are pretty reliable once you have system DLL symbols hooked up (highly recommended), but I still occasionally run into cases where VS2005 can't fully decode a stack that WinDbg can. Also, loading system symbols can noticeably delay program launch -- it seems to be a bit slower than VS2003.
The debugger has a new feature where it can follow data structures based on a description in autoexp.dat and display the contents as a flat table; this is a godsend for debugging STL code. Less well known, however, is that this feature is also useful for non-containers since the expression evaluator for the visualizer is more powerful than the old autoexp one and can evaluate expressions that access more than one member variable.
You can now bind an action to a breakpoint instead of just breaking into the debugger, the most common of which is to print out an expression value ("tracepoints"). Don't think this is useful, because you can just add a print statement? Try dropping a tracepoint into assembly language code.
The debugger now verifies source code checksums and can tell you when you are debugging against the wrong version of a source file. Very nice.
Debug output speed is improved somewhat compared to VS.NET but is still far below VC6 and NTSD/WinDbg (101808).
The new help system is SLOOOOOOOOOOOOWWWWWWW. As in, hit F1 and wait ten seconds for it to come up while it parses all of the help files in the system. Once it loads, it's not bad, though, so keep it loaded.
F1 context lookup is a little better than VS2003, but still fails very badly for many Win32 topics (111719). It still very often brings up the .NET Framework, MFC, ATL, MAPI, FoxPro, Windows CE, or pretty much anything but the Win32 topic you are looking for. The set of filtering checkboxes for search works decently well, though, and the granularity for selectively installing help in the setup program is also improved.
There is now support for online documentation, which is useful for when you don't have disk space to bring down MSDN (debugging on someone else's machine), or want to look at newer documentation. When I was using Express, though, I wished it could integrate into the index.
I still find the .NET Framework documentation hard to read. The hover popdowns are disconcerting, and the layout is messy -- I have to jump through a few levels of topics including the class overview, class definition, and then the member, and finally the member list is polluted with all of the inherited members from all the way down to Object (which makes the list very long for WinForms objects).