views:

500

answers:

10

So, we saw the post on Code Smells and how to fix them...but what about for us NON object oriented folk? I use embedded C a LOT and while all the responses to the said post were great, I wondered if anyone had some input about the straight-C world? Some of the things mentioned in the other post do not apply (and some were even completely opposite) to my world... What do you guys think?

+7  A: 

High Cyclomatic Complexity still applies. A function with a high cyclomatic complexity is a sign that the code is too complex and likely to have bugs and that bug fixes are likely to have bugs!

http://en.wikipedia.org/wiki/Cyclomatic_complexity

Edit: Source Monitor is an excellent tool for gathering Cyclomatic Complexity. http://www.campwoodsw.com/sourcemonitor.html

torial
Very cool. Thank you for the link as well...I will look into this metric to see if I can apply it to anything I've been working in.
MaTT
+4  A: 

goto

using non secure versions of functions

code files with over 2000 lines of code

ScaleOvenStove
The idea is one thought per answer.
Geoffrey Chetwood
Agreed. One thought per answer, plus possible solutions or at least a reason why this is a bad idea.
MaTT
Can't even imaging coding without goto. This is the only way to make a proper cleanup. Like C way of try catch mechanism.
Ilya
A: 

How about Tail Call Optimization:

    int bar(int a)
 {
     printf("bar called with arg %d\n", a);
     return a * a;
 }

 int foo(int b)
 {
     return bar(b * b);
 }
Geoffrey Chetwood
could you elaborate? I'm not sure what you are pointing out
Benoit
+3  A: 

Deeply nested control structures (ifs inside switches inside loops and so on) usually mean it's time for a good refactoring session.

marijne
Yeah, I see this pretty frequently. This seems to come up more often when working with legacy code...some of us are so afraid of breaking things that we just throw in a conditional block inside of some giant switch statement. Thanks!
MaTT
+5  A: 

functions that take a gazillion of arguments always smell..

Nils Pipenbrinck
+3  A: 

large functions (with more than 200 lines of code, or more than one screenful, pick something)

Benoit
Where did you come up with 200 lines as a line to not cross? I, too, don't like lengthy functions...makes maintaining it a nightmare, too! Just curious if there is a standard somewhere that has the clear-cut line to not cross. Thanks!
MaTT
Totally out of thin air... various sources suggest one screenful.
Benoit
+1  A: 

function calls using post/prefix increment - foo(i++)/foo(++i).

This can lead to undefined behavior - foo(i++, i)

Benoit
eww! People do that!?! Luckily I haven't seen it. Good post though! Man, I'd rip that apart in a code review. Haha.
MaTT
+2  A: 

use of Magic Numbers!

foo = 75;
vs.
foo = MAX_STRING_LEN;
Benoit
I see this very often. I even fall into this myself, thank goodness for code reviews! It's a very good one to note.
MaTT
+3  A: 

unhelpful variable names

i,j,k as loop variables are ok, but what does this do:

tt = (a * st) * ct;
t = a + tt;

The following should be clear to everyone:

total_tax_amout = (amount * state_tax_rate) * county_tax_rate;
total = amount + total_tax_amount;

It's almost self-documenting code! :)

Benoit
Yes, the county tax rate is applied OVER the state rate...argh...
Benoit
Nice example! Thanks.
MaTT
+5  A: 

Here's a really bad smell: defining macros to replace the basic syntax of the language, like

#define BEGIN {
#define END   }

Don't laugh! I had a programmer at my first job who was very proud of having made his C code look like Modula-2.

Ben Combee
That is just flat out crazy. Why would you add in that extra level of complexity and work? Nice post!
MaTT
Granted, that job was around 1992, and it was in a small town where the programming staff were either COBOL people or rather eccentric.
Ben Combee