tags:

views:

108

answers:

5

I have the following problem that other people must have encountered. I am working on a code base that runs on two different platforms. Most of the code is shared between the platforms, but some parts of the code are optimized for a particular platform. So, there may be a generic implementation of function foo() in file foo.cpp and an implementation optimized for platform A in file foo_A.cpp.

Of course, what sometimes happens is that a developer modifies foo.cpp and forgets to make a corresponding change to foo_A.cpp to keep them in sync. This leads to very unpleasant bugs, that are hard to track down.

Finally, here's my question: is there any way to "entangle" two or more files in Subversion? Is it possible whenever one commits a change to foo.cpp to have svn issue a warning, a reminder to update foo_A.cpp?

+7  A: 

You could write a pre-commit hook that checks to ensure that both foo.cpp and foo_A.cpp are present when either one of them is committed.

It could either just present a warning message and continue, or actually fail the commit by returning an error, your choice.

RedFilter
+3  A: 

Subversion has hooks that you can use. Basically, you write a script in the proper folder and with the correct name. It can check to see whether a specifically named file is checked in, then do a bunch of stuff in response. (In other words, you could automate updating one file every time another file is checked in.)

This is generally a bad idea. Restructuring your projects so you all share the same file is usually a better solution.

John Fisher
I don't want svn to automatically update the other file. That would indeed be a bad idea. Ideally, I want it to give me a dialog box/prompt that says "You've modified foo.cpp, but not foo_A.cpp. Are you sure that's ok? You should really check, because now foo.cpp and foo_A.cpp may be doing different things." And I want it to abort commit, if I don't say that's ok.Sticking code for different platforms into the same file is a bad idea, IMHO. It is better to have platform-specific code in separate files and deal with them at the build configuration level.
Dima
A: 

You might also want to have unit tests against that file, run on both platforms by continuous integration - then changes that break only one platform might be detected. At least it would verify that both implementations expose the same interface during compilation.

Douglas Leeder
It is not really a question of breaking the interface. I may tweak the algorithm somehow in the generic implementation, keeping the interface exactly the same, and then forget to update the optimized version. In fact, this is exactly what happened. :(
Dima
+1  A: 

Since you are using a compiled language, have you considered just writing #ifdef's (checking for flags defining the platform) in the functions for the optimizations instead of just writing a whole new function?

ocdcoder
btw, i know this doesn't answer his question about svn. I was just saying for best practices sake. I don't know his situation, so this may not be a better solution, but just wanted to see if he had considered it
ocdcoder
#ifdefs are often frowned upon in the C++ world. It is better to resolve these issues in the build configuration than at the preprocessor level. Check "Effective C++" by Scott Meyers. Besides, even with ifdefs it is still very easy to forget to update the other version of the code.
Dima
Gotcha, i come from a mostly linux-based C world and don't have much experience (besides educationally) with C++. Just wanted to toss the idea out there though to see if it helped. Thanks for the info!
ocdcoder
+2  A: 

You can use a pre-commit hook to reject the commit if foo.c is modified as part of the commit but foo_A.c is not. Depending on how many files are in your project, this may be difficult to manage by listing the files explicitly in the hook script.

If you have some consistent file-naming conventions, you may be able to put some intelligent pattern-matching logic in the script. (e.g. if you know that the names of the optimized files always end in "_A", you can automate the checking a little easier.)

As an alternative, you can try to solve the problem in your build process. The build script could do an "svn info" on the two files, and then throw a warning/error if the SVN rev numbers of the two files don't agree. It could be difficult to detect if the rev numbers are different for legitimate reasons, though (e.g. you edited only one of the files deliberately).

However, as the commenters have pointed out, I honestly feel that you are trying to solve the problem incorrectly. I would be trying to structure the code to prevent this class of errors from happening in the first place. If both functions need to change at the same time, this is a sign of unnecessary duplication in the codebase. Look at consolidating the common elements of the two files in one place.

msemack