I am a newbie who just graduated.
I found my first job and begin to review some legacy codes

And I find out there are a lot of macros which could be replaced by function
(somebody especially c coders may think macro is a better choice)
Not even that, I almost could swear that the designer did not think carefully
before designed, there are a lot of weird interfaces,
what is the meaning to design something like

public :
  int getNum() const;
  void setNum(int const num);
 ................

protected :
  int num_;
.....................................

A lot of inline codes, even constructor and destructor
yes, there are nothing in the constructor and destructor, but there are a lot of "unseen" constructor and destructor
would be called implicitly, I could only hope that the compiler would be smart enough to reject all of the
unnecessary inline functions.

The worst thing maybe is "copy and paste"
Oh man, maybe this is one of the most cunning evil of programming

I believe there are other problems, and maybe it is worse than what I have covered up until now

I know our company is a small company
But I never imagine our legacy codes could be so **** poor
Are those beautiful codes only existed in those textbooks
which wrote by those masters?

The most important thing is, what should I do if there are a lot
of "copy and paste", weird interfaces(meaningless), more and more prone to error
macros?Because our codes are pretty fragile and a lot of bugs, prone
to crash. I just know that our company seldom or never review codes,
because we don't have times to do that. When bugs pop out and they failed
to find out the reason, they would just write some work around to cover it.

What would you try?Any good ways or books?Since this is teamwork, I cannot
insist my opinion, but to follow the rules of the company.
I don't intent to leave this company in one or two years, except of producing
some ugly codes like that again, what could I do to make my life easier?

Thanks

ps : I can't change the legacy codes, because they don't want to see any bugs occur
yes, it is reasonable. No matter how poor the codes could be, it is very hard to
change it when it is widely spread within the whole product...
Now I only hope there would not be too many bugs hide in those legacy codes

In the real world, codes are different compared to academic codes. There are many reasons for that.

1)Academic projects are often much smaller than real world projects. Expecting a huge codes to be well designed would take a long time to finish. I mean, you wouldn't start coding right away. You will have to go through requirement gathering and design which are long long processes.

2)Sometimes you need to do a quick fix to the project code. The code could be from you alone or others. In order to fix and finish it on time, you may simply copy & paste or add macro to it. As a result, the original well design code becomes uglier and uglier. You will see how it is after you work for a while.

3)The requirements may also be changed by client or your company after the implementation phase due to unexpected reasons. You may not want to dump the whole implemented code because it will take a lot longer time to implement the whole thing again. As a result, you just modify it (quick fix).

Therefore, you may not expect any legacy code to be perfect. Nothing in this world is perfect anyway...

Edited 5 Years Ago by Taywin: n/a

Welcome to the real world. :)

Not to defend bad programmers, but often you'll find yourself divided between writing "bad code" and <insert undesirable business result>. 9 times out of 10, the lesser evil is writing bad code, and that's a harsh reality that newbies need to come to terms with. Successfully juggling programming concerns with business concerns is the difference between a good programmer and a good software developer.

Legacy code in particular has a lot of smells because it's been evolving for a long time. While best practice is to refactor as the code evolves, that's very time consuming and can easily introduce bugs.

As far as funky design decisions, in my experience there's always a reason. Sometimes the reason might be an inexperienced developer, but more often it's an environment limitation/dependency or a legacy practice that has since been superseded but the code wasn't changed due to excessive costs.

My recommendation is to improve what you can, and don't sweat what you can't.

I'm not a great expert in business concerns in software developments, so take my opinion for what it is worth.

It does seem that your company has been camping itself strongly on the side of "lets get the software done asap", as opposed to "lets build a robust and sustainable software project going". Personally, I balance more towards the latter. General software development experience has taught people that neither extremes are practical. If you "just get the software running", you usually carry a large handicap for future development in the form of poor abstractions, ill-defined interfaces, un-resolved silent bugs, etc. If you "make a master-piece of software engineering", you might never see the end of it, but at the same time, your development cycle is a lot more predictable (e.g. if you always do rigorous unit-tests, you never get surprised by a horrible bug that requires a lot of programming to fix and causes delays that weren't planned for).

In other words, the former approach allows you to plan for a shorter development cycle, but you also have to plan for a lot of contingency, and you might spend more time in contingency recovery than on actual development. While the latter approach will certainly increase the length of your development cycle, but the time you have to plan for contingencies is small. It all depends on which approach leads to the smallest sum (developing + fixing). The main problem with the "real-world" is that many people (especially in the management layer) only factor in the development time.


So, your problem is "a set of horrible legacy code". As said, in theory, the best solution is to refactor it all to bring it up to current coding standards at your company (whether their current coding standards are good enough is another concern to fix in theory). But that might be either too much effort, too dangerous in introducing bugs, or not easy to sell to your manager. In other words, real-life concerns destroy the "theoretically" recommended option. Nevertheless, I would also add the real-life concern that using poorly designed code can impede the future developments in the project, it is like a big dead-weight to carry through the entire remainder of the development efforts, this is a real-life concern that argues for refactoring the code.

Considering that refactoring is not a viable option, the option that I would recommend is to do as much as you can to improve the quality without making significant changes to the code. Now, that includes making serious unit-test programs to put the legacy code to the test to make sure it doesn't have silent bugs. Once the quality of compiled code is determined to be good, you can assess the quality of the source code, as in, how much it pollutes the rest of the source code (e.g. with MACROs) and how bad the interfaces are. To solve issues that you find with the quality of the source code you can use two simple techniques: write adaptors to re-work the abstractions and interfaces of the legacy code without having to change it such that the code that you write that needs to use the legacy code doesn't get infected by the poor design of that legacy code; put the legacy code behind a compilation firewall to limit the code pollution.

In other words, a little like Narue said, improve what you can and what affects you, don't let the ugly legacy code effect ugliness on your new code. Test its safety, isolate it, and hide it, just like you would do with any other kind of toxic waste.

I would not try to rewritting something I don't understand
Except of some thing which easy to do
like make those unproper inline function become non-inline
or wrap those redundancy codes by template

And I forget to say another very importang thing
The codes lack well document and explanation
only a few lines of comments for classes and a few of functions

I know they are busy, but no matter how busy a programmer could be
Programmer should write comments, else the codes would become very hard to maintain

Programmer should write their program on a paper first before they try to implement it
except of some extremely easy cases.
It is very irresponsible to write codes without comments and verify your codes
on paper before you begin to write codes

Sometimes my comments of my codes are more than my source codes
The times I spend on writing comments are same or even more than develop source codes

Well document is very important when develop software
What if someday those programmers all leave?
Who could decipher those legacy codes?
Writing document may spend many of times, but it is worth to
Especially when you want to maintain your codes

The best comments is don't need any comments
But this is real world, even the lib which developed by those top programmers need to be well documented
look at boost, openCV, loki and so on

Yes, comments can't execute, but as the source codes become bigger and bigger
you will realize it is worth to. In the long run, good document could save you a lot
of times, and times mean money.

The sad thing is, this is real world. So I should not write any comments since our
company do not treat this seriously. Why should I behave a good discipline since
another treat it as bad habits and unneccessary?Don't act different else you will
become a jerk, this is nothing related to "correct" or "wrong", just act like you
are with them if you don't want to have a hard life.

ps : I just found two bugs yesterday, and looks like it is hidden in our source codes long ago,
cause by copy and paste(the function always return false)

Edited 5 Years Ago by stereomatching: n/a

>>like make those unproper inline function become non-inline

Inline functions are not a problem. In general, small functions should be inline (e.g. set/get functions, empty constructors, etc.). Inlining is a very important optimization, and non-inlining just for the benefit of not having any function definitions inside a class declaration is an unnecessary pessimization of the code. Just thought I would point that out.


I agree totally with your "rant" on commenting the code. The habit of writing comments on the interfaces of code (i.e. in doxygen style) is one of the top qualities I consider a programmer can have.

I find that one good way to motivate people to use documentation is to generate a doxygen documentation from the code, with the option to "hide undocumented members". Then build a culture of referring to that doxygen document (usually nightly built on the source code server) instead of digging through the actual source code when looking for functions to use and stuff. This way, developers are strongly encouraged to document their "usable" code well such that others can find it in the documentation instead of always coming to him/her with questions or misusing his/her code.


>>Don't act different else you will become a jerk

This is not a problem of what you do, it is a problem of how you do it. You shouldn't position yourself as the "guy who knows better" or the "evil code scrutinizer" or whatever. Be humble. Just write your code in the best way you can, and document it well, to your satisfaction, but don't spend your time trying to proselytize "your way" to everybody else. If you have problems like you try to use the code of a colleague, and you find that it isn't clear how to use it (because of a lack of commenting), then just ask that colleague for clarification on the usage of his code, and then suggest that he adds the clarification to the code-docs because it will make his code easier to use. People tend to respond well when you are "on their side", if you approach it as "I think your code is nice and could be really useful to me, but it would be easier to use with clear documentation of its interface because X, Y, and Z are un-clear to an outside programmer". Generally, if you show people how helpful it is to have good documentation they are usually happy to improve their own code and put it in a better light by doing so themselves. It's all about assertiveness and leading by example.

Edited 5 Years Ago by mike_2000_17: n/a

Comments
because I can't get back to evil school , I decided to keep my job, so I ignore the pain and pratice to enjoy reading others crypt code. Ture , always become liberal will made others liberal to you.
Inline functions are not a problem. In general, small functions should be inline

I agree with you, because I experiment with it. Proper inline could boost up
the performance drastically

But this also incur that if some member function are trivial, always be called
and the performance is very importance, it is not a good idea to use virtual

Besides, I also try to see the results of "improper inline"
The codes becomes slower and fatter due to it
(it depends on the compiler, gcc4.5.2 reject my apply)

The problem is, our destructor and constructor are inline too

class base
{
  std::string;
  type_A;
  type_B;
   ......and so on  
};

class derived_A : public base
{
  private :
    type_C;
    type_D;
    ......and so on
};

class derived_B : public A
{
  ...a lot of data member....
};

many of the constructors and destructors are looks like these

inline xxx::xxx() : a(), b()....... {}
inline xxx::~xxx() {}

According to effective c++ third edition, item30
This is not a good habit(hope that the compiler would omit the inline)
C++ do many thing behind of us, we have to know
what kind of dirty jobs the compiler may or may not
do for us.

Exactly, this is hard and too many things too learn
if I have to get along with c++
choose c++ as my major tool "push and force" me to study
Because there are too many things could be controlled

Edited 5 Years Ago by stereomatching: n/a

Forgot to said, thanks to your advice

Sometimes I am thinking, maybe we should use another tool to develop
if we "don't have time" to review the codes, write documents and need
to dump the codes asap.C++ is prone to errors if you don't spend your
time to handle it carefully and very hard to maintain when compare to
other'slanguage.

The power of combining template(GP) and oop are extremely powerful, but
when the target of our company is "dumb the codes asap", I would not
recommend c++ if I were the boss.

Whatever, I have many things could learn from my first job, even I can
change the policies of our company, I could discuss with other's experience
coders and learn from them.Like why are you design something like this?
What would you do it again if you have a change and so on.

This article has been dead for over six months. Start a new discussion instead.