5

I work on a large software product which, being over 20 years old, has a number of constructs which have been superseded by language updates.

One of these is a home-rolled smart pointer template class which acts similarly to - but is not quite indentical to - std::unique_ptr. The class has its destructor specialised for a number of types with specific destruction needs, and is referenced of the order of 150-200 times. It apparently works perfectly.

Were the application to be written from scratch now, I'm reasonably certain that std::unique_ptr would be used instead. How aggressively should we pursue replacing the home-rolled class with std::unique_ptr; possibly including typedefs for the common specialisations with specific destructors?

  • 9
    Can you name the largest disadvantage that keeping the legacy solution would bring? 'cause if there isn't one, the answer is easy: do nothing. – Kilian Foth Apr 4 '16 at 8:53
  • 3
    If it ain't broke, don't fix it. I know this sounds funny, but it's actually true. If the current solution works, on top of the fact, that the current solution effectively delivers the seeked functionality, people working on the project are very likely to be already familiar with the API of this class and do not need to learn anything new. – Andy Apr 4 '16 at 9:05
  • Is it already possible for new code to use std::unique_ptr if it's deemed desirable, or are there certain in-house libraries that would have to be changed before that's practical? Otherwise I think I agree with Kilian. – Ixrec Apr 4 '16 at 9:17
  • 1
    The legacy class 1) needs to be known about - I had a code review rejected for using unique_ptr for an already-specialised class. Granted, I now know about it... 2) doesn't match unique_ptr in semantics, possibly leading to unexpected behaviour. However, no, it's not broke, and unique_ptr is fair game for classes not already specialised. – Chowlett Apr 4 '16 at 9:52
  • 1
    You should not embark on any project to replace any core system (like unique_ptr) without a clear and well-thought-out plan on how you will deal with the bugs that will result. Most legacy systems do not have robust sets of tests. – Steven Burnap Apr 4 '16 at 15:59
5

This is a common problem for maintainers of old/legacy code, and there is no single perfect answer. Before making the decision to replace working code, I would propose trying to answer these three questions.

  1. Is it possible? Can you devise a method whereby existing instances of the 'old way' can be reliably replaced by the 'new way' such that each change is guaranteed to be made correctly, to be tested and to pass all tests, and that no new bugs will be introduced?

  2. Is there a benefit? Can you identify any aspect of the code that will be better after making this change? Will the code be faster/smaller/more maintainable as a result of the change? Will making the change uncover bugs you didn't know about? Is the benefit large enough?

  3. Is it enabling? Is this code under active development and there is some other planned set of changes that becomes possible/easier/safer as a result of first making this change (which would offset the risk of introducing bugs and the lack of a direct benefit)? Or is this a mature, stable code base that really needs to be protected against tampering by enthusiastic newcomers?

This last is often the decider. If there are big changes ahead for this code then getting rid of obstacles like home-brew templates might well be justified, where otherwise it is usually best to let sleeping dogs lie.

  • Excellent questions to ask, and I probably don't know the answers of the top of my head. I suspect that 1) yes, it's possible; although we sorely lack enough tests to be perfectly sure; 2) the "only" benefit would be maintainability (and new coder orientation); 3) as the entire codebase is under dev, it would have a benefit of some size. Which probably amounts to "worth considering changing, not a complete shoe-in". – Chowlett Apr 5 '16 at 8:55
  • @Chowlett: Just so. My aim was to give you (and other readers) some very specific questions to ask yourself. When you can answer those questions, you should be able to make an informed decision. For some perspective, think about Microsoft and how the code base underlying Windows, Word and Excel must have changed over the past 30 years, and think about the cost, and the bugs! – david.pfx Apr 6 '16 at 1:24
2

The main advantage of doing this replacement would be the cost of bringing in new people.

If you bring in a new C++ programmer, they will have to learn the particulars and vagaries of your smart pointer. Whereas if you used unique_ptr, there is a reasonable chance that they already know its peculiarities. And if they don't, then there's an entire Internet of information about it. That's one of the things that makes vocabulary types good: everyone already knows how they work, and if not, information is readily available.

You mention that your smart pointer has special code structures that are designed to interact with specific other classes. That's represents non-trivial domain knowledge that users of that smart pointer need to know. Such domain knowledge must not only be acquired by new programmers, this knowledge will for the most part be useless outside of your project.

Whereas time spent understanding unique_ptr will be valuable over one's C++ career.

That's not to say that you necessarily should make the change. But that would be the primary advantage in doing so.

1

This is a problem for many legacy systems. On one hand, this custom std::unique_ptr-like capability has been around for a long time. Bugs were wrung out long ago, and people on the project know how to use it. "It ain't broke, so don't fix it".

On the other hand, it is broke in a sense. One of the biggest challenges facing older solutions to some problem is competition that has emulated what you have done but have done so using modern techniques. That competition will surpass you if you don't continuously improve your processes and your product. This custom std::unique_ptr-like capability is most likely one of many techniques in your twenty year old system that, while innovative in their time, are now archaic, cumbersome, and are slowing down your development process.

  • 2
    That competition will surpass you if you don't continuously improve your processes and your product. - True, but only where process and product actually need improvement. The only pro-change argument you're making here is modernity, but altering proven code solely for that reason introduces avoidable risk. – Blrfl Apr 4 '16 at 12:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.