tags:

views:

250

answers:

5

We are currently busy migrating from Visual Studio 2005 to Visual Studio 2010 (using unmanaged C/C++). This means that about half of our developers are already using Visual Studio 2010, while the other half is still using Visual Studio 2005. Recently, I came into a situation where a certain construction can be written in a clean way in Visual Studio 2010, but requires less-clean source code in Visual Studio 2005. Because not all developers have already Visual Studio 2010 on their machine, I have to write the code like this:

#if _MSC_VER >= 1600
   // clean version of the source code
#else
   // less clean version
   // of the source code
   // requiring multiple lines of code
   // and requiring some dirty static_casts
#endif

Since all developers will migrate to Visual Studio 2010 by the end of this year, I want this code to 'disappear' automatically after a certain moment. Keeping the 'less clean version' in the source code results in unreadable source code in the long-term.

Of course, I know that code doesn't automatically disappear, so I actually want an automatic alarm bell after a certain moment. Something like this:

#if _MSC_VER >= 1600
   // clean version of the source code
#else
   // less clean version
   // of the source code
   // requiring multiple lines of code
   // and requiring some dirty static_casts
#endif
#if compilation_date is after 1 november 2010
#   error "Remove Visual Studio 2005 compatibility code from this file"
#endif

That way, if we forget about this, we are automatically notified of this after 1 november 2010.

This trick probably requires the use of DATE, but since this needs to be handled by the precompiler, you can't perform string-manipulations or use the C date/time functions.

I also considered the alternative idea of just sending myself a delayed mail, but I was wondering if there wasn't a solution that could be built in in the source code.

+1  A: 

I'd just use a preprocessor define like #ifdef WARN_OLD_COMPAT. With the delayed mail you will then remember you to define this.

Checking if the compilation date is later than <X> is not possible in other ways.

Uli Schlachter
+1  A: 

Why not just do the check at runtime in dev builds? Surely you test your code, so the first time someone tests it after the date, you'll get the notification.

Peter Alexander
I prefer checking things at compile time rather than at run time.
Patrick
As do I, but in this case, there's no harm in checking at runtime.
Peter Alexander
+14  A: 

In case of GNU make I'd do it like this:

CFLAGS += -DCURDATE=$(shell date +%Y%m%d)

It will add a macro CURDATE to compiler flags, that contains the current time in YYYYMMDD format.

So in source you could do something like this:

#if CURDATE > 20101101
#error "Do whatever you have to do"
#endif

Can you do something like this in VS?

qrdl
Good idea, thanks.
Patrick
+1, very clever.
Greg S
A: 

This may be helpful

Chubsdad
+6  A: 

Personally, I would choose to disbelieve that everyone will actually migrate by the expected date. Even if I'm confident that it's going to happen, I don't want to create extra work for anyone, or stop them working, in the event that I'm wrong.

If nothing else, builds should be reproducible. What if, in December, you realise that you need to reproduce a build from October? You can't (at least, not without bodging the clock on the build machine), because it won't compile any more.

So, I'd do this:

support2005.h
-------------

// empty file

source file
-----------

#include "support2005.h"
#if _MSC_VER >= 1600
   // clean version of the source code
#else
   // less clean version
   // of the source code
   // requiring multiple lines of code
   // and requiring some dirty static_casts
#endif

Once everyone has VS 2010, change support2005.h to contain #error "Remove Visual Studio 2005 compatibility code from this file".

Actually I personally wouldn't check that change in, since it will prevent anyone from doing any work until VS 2005 support is removed. Is removing dead code really the highest priority task your company might possibly have on the morning of 1st November? And does it require all hands on deck to do that? Rather, I would check out, delete the file, do a full build, keep removing compatibility code until everything build again, and check the whole thing in as, "remove VS 2005 support".

You say you're worried you might forget, but if you do, so what? The dead code isn't hurting anyone. You'll remember it the next time you look at any of those files, or the next time you see "support2005.h" in a file list, header dependency graph, etc. So it's not "making the source code unreadable long-term", because long-term anyone who sees it can just ignore or delete it. If you have any kind of issue-tracking software, you could find the first milestone targetted after 2010-11-01, and attach a task to it, "remove VS 2005 support, and get rid of support2005.h", with a note that this is currently blocked by developers still using VS 2005.

If you really want 2010-11-01 to be a hard deadline, after which the code breaks, then just stay up until midnight on Halloween, and check in the breaking change then. It doesn't actually break the code, as you requested, but it does break anyone who refreshes from source control, and hence presumably it breaks the build. Most importantly, it's very easily reversible, or can be suppressed locally, if it turns out to stop someone getting work done.

Steve Jessop
Nice arguments. You certainly have a point about "builds should be reproducible". I don't agree with the "dead code isn't hurting anyone" approach. Dead code can/will confuse developers. Recently we had a problem with someone modyifing dead code to make it work with changes in the internal data structure. So I think that dead code must be removed (although the 1st November is probably not a good moment). The "support2005.h" idea raises an even better idea: why not use /D_SUPPORT2005 to define the _SUPPORT2005 symbol, and let compilation fail if this symbol isn't here, but old code still is.
Patrick
Fair enough, I was assuming that it would be widely known in your organisation that this temporary 2005 support was necessary. If so, then once it's no longer needed, it *shouldn't* confuse anyone or cause unnecessary work, because anyone thinking of modifying it could instead remove it. I agree that in general dead code should be removed for the reasons you say.
Steve Jessop
What if someone removes the old code but does not remove the header. Next time they see the error, they would have no idea what needs to be done, because all the old code is already gone!
Lazer
There are a lot of bad things that can happen if someone half-removes code. The `#include` line is right next to the `#if _MSC_VER` line: what more do you want? I guess you could replace that test with the use of some macro, which is later changed to something that would cause a compilation failure. Then if the code is removed, the macro is no longer used, so the redundant header inclusion causes no harm.
Steve Jessop