Fog Creek Software
Discussion Board




Evolving code layout style! You be the judge!

After 15 years of C programming, my code
layout style has evolved mostly from external
influences and dealing with problems of
large teams working on the same large code base.

When it comes to function declarations, prototypes,
and even function call statements, I have progressively
evolved from FuncStyle1() -> FuncStyle2()
-> FuncStyle3() to currenlty FuncStyle4()
(see examples below)

The interesting thing is that most of my co-workers
alwasys seem to STOP evolving at 2() or 3() and their variations.

I recognize that the biggest _potential_ gains comes from
FuncStyle1() -> FuncStyle2(), and that 2->3->4 can
be debated on the merits of "dimished returns".

However, i am wondering if anyone in the _community_ can
think of valid general argument(s) as to WHY FuncStyle4() is
better _on average_ then 3 and/or 2???  The only diff
between 3 and 4 is the comma placement!

//-BEGIN CODE -------------------------------------
// jam packed arguments on 1 (or more) lines
void FuncStyle1( int arg1, int arg2, int arg3,
                          int arg4, int arg5, int arg6)
{
    // implementataion
}

// marshmallow packed arguments
// uses more white space with
// commas at the END of the argument lines
void FuncStyle2(int arg1, 
                          int arg2,
                          int arg3,
                          int arg4,
                          int arg5,
                          int arg6)
{
    // implementation
}

// use much more white space and many more lines
// commas at the END of argument lines
void FuncStyle3
(
    int arg1,  // optional argument line end comments
    int arg2,
    int arg3,
    int arg4,
    int arg5,
    int arg6
)
{
    // implementation
}

// use much more white space and many more lines
// commas at the BEGINNING of argument lines
void FuncStyle4
(
    int arg1
,  int arg2    // optional argument line end comments
,  int arg3
,  int arg4
,  int arg5
,  int arg6
)
{
    // implementation
}
//- END CODE --------------------------------------------

Heston Holtmann
Friday, May 23, 2003

In my (oh so humble) opinion...

Function style 1 is more than adequate, if you full document the parameters in the comment block above the function.

For example, for those that use Doxygen (as I believe you do Heston), you should do:

///////////////////////////////////////////////////////////////
/// @param one  [in] description of one
/// @param two  [in] description of two
/// @param three [in, out] desciription
///

etc.

For those that do not use function/method comment blocks, any variation of your examples 3 or 4 is acceptable.

Happy to be working
Friday, May 23, 2003

Oh, and before you yell at me for not asnswering your actual question.....

example 1 is great.
example 2 is bad.
example 3 and 4 are okay.

I would personally use 3, although I use example 4 when I initialize vars in a constructor.

Gerald

Happy to be working
Friday, May 23, 2003

They're all fine - the compiler won't generate a warning or error from what I can tell.  The rest is human preference.

Opinions are like assholes.  Everyone has one.

Nat Ersoz
Friday, May 23, 2003

I aggree.. FS1() is adequate.

they are _all_ adequate!

But i wasn't asking about adequacy (sp?)..

Even if every function was properly documented and commented, and 100% bug free, etc, etc.

I still think/feel it is a valid question to ask "Is 4() in any way slightly better then 3()".  I think/feel valid reasonable answers also exist to the question.

For example, one of my team-members claims that 3() is better then 4() because the English language has always put commas at the _end_ off phrases and passages and that humans are trained to trigger of the comma's at the end!

I do have my own answers!  But I am more intersted in other's people's answers.  Especially if the answers can convince me that 3() or 2() is better then 4().

Heston Holtmann
Friday, May 23, 2003

I actually find style 4 almost painful to read.  The commas are not significant, they are just there to separate the parameters.  Why are you promoting them to placement at the front of the line where they stick out like a sore thumb?  The only advantage I can see with this is that you don't have to change the line of the last argument to add one more (thus simplifying change logs).  That seems like a pretty trivial advantage to me, and definitely not worth making it harder to read

Personally I use style 2 a lot, though the indentation can get unwieldy for long function names so sometimes I fall back on style 1

Mike McNertney
Friday, May 23, 2003

IMHO:

4 is awful.
1,2 and 3 are a matter of taste. I prefer 1. But my Java IDE formats the code automaticlaly as 2 and it's OK with me.

Why I think 4 is wrong: code is written for other people to read. Therefore, formatting style shlould be optimized reading, not for writing.

raindog
Friday, May 23, 2003


I don't like 4... the commas at the beginning do stick out like a sore thumb.  I've seen this in SQL queries, where the thought is that more attributes might need to be added and someone is prone to wind up with an extra comma at the end.

Personal preference... I like 1.  The list takes up too much vertical screen space.

Joe AA
Friday, May 23, 2003

Mike McNertney...

Now your on to something..

Lets just say your response has some "weight" to it!

Your the only one so far that did some critical-thinking before responding instead of just _complaining_ like everyone else!  Thank you!

I will have to wait until this weekend to follow up with my reasons WHY i have abandoned 3() in favour of 4(). 

But basically my reasons can be represented mathematically with the following formula:

  0.4 = weight of Trivial Advantage A
+0.3 = weight of Trivial Advantage B
+0.1 = weight of Trivial Advantage C
+0.1 = weight of Trivial Advantage D
+0.1 = weight of Trivial Advantage E
= ========================
=1.0 Significant Advantage to 4() over 3()

Heston Holtmann
Friday, May 23, 2003

i like #1 for declaring the function and implementing it
i like #2 or #3 for using it elsewhere (to organize the args)

apw
Friday, May 23, 2003

you must have a very boring job, or not enough to do.

victim, jr.
Friday, May 23, 2003


Adding up the weight of an advantage means nothing without balancing it with the weight of a disadvantage.

Joe AA
Friday, May 23, 2003

I think that this:

void FuncStyle5 (
int arg1,
int arg2,
int arg3 )
{
// ...
}

I easier to read than any of the other four. The { line already essentiall creates a line of mostly whitespace between the function header and body. One line per arg looks good in changelogs, scales well to high numbers of arguments (although I generally try to avoid high numbers of arguments) and makes it easy to do inline comments on arguments.

I like style 1 right up until it becomes necessary to line-wrap because there are so many arguments. That generally signals to me that it some refactoring is needed.

But I'm quite interested in seeing Heston's reasoning for putting commas at the start of line beyond minimizing number of changed lines.

dmooney
Friday, May 23, 2003

Imagine that there is one or two tabs worth of space in front of the arguments in FuncStyle5. I did not intend for them to be left justified.

dmooney
Friday, May 23, 2003

Commas in front:  you can add params without changing the previous (needing to add a comma to the previously last argument).

Lame.

Nat Ersoz
Friday, May 23, 2003

Commas in front is something I've come to appreciate lately.  I've been modifying enough code that's set up this way that its absolutely a pleasure to add and remove parameters - when I run across code that's not set up this way (see 3) I've found myself missing a comma and wasting a lot of time on a bad compile.

Lou
Friday, May 23, 2003

I use 1 when the function has a few arguments.

I use 3 when the arguments are numerous or if long names would make the line too "long". (3 seems over kill for single argument functions.)

I don't like 4 because of the commas in front (but it's otherwise very close to 3).

2 is miserable because it's different for each function. Also, if you change the name of the function, you have to align a bunch of other lines. If a formatting style requires aligning stuff like this, it's fussy and wastes time.

The nice thing about 3 (and 4) is that it is the same for every function and it's easy to do with standard indenting.

3 (and 4) is much easier to implement as a standard than the yucky 2.

njkayaker
Friday, May 23, 2003

The advantge of 4 is that you can add/delete arguments without changing other lines (in style 3, if you add an arg7, then you also need to add a comma at the end of the arg6 line, which makes the arg6 line show up in a difference editor). That said, I don't like functions which take so many arguments: why not pass a structure or two instead.

Christopher Wells
Friday, May 23, 2003

The indentation of the subsequent lines in 1 & 2 are bad because if you change the function name you have to change all the indenting. See Code Complete for an exhausting presentation of this point of  view.

I use a style similar to 3.

4s advantage is that you can easily add new parameters with out forgetting to add the comma to the former line and not include it on the new one, saving a  compile, observe error message, change code, recompile step.

My #3:

int SomeFunction
  (
  int a,
  int b,
  int c
  )
{
  int result;
  SomeCode();
  result = SomeMoreCode();
  return result;
}

Dennis Atkins
Friday, May 23, 2003

I end up using a combination of (1) and (4)

"He's inconsistent!  Burn the unbeliever!"

Well, not quite (4).  I put the opening paren on the same line as the initial argument:

void FuncStyle4
(  int arg1
,  int arg2    // optional argument line end comments
,  int arg3
,  int arg4
,  int arg5
,  int arg6
) ;

When working with initializer lists in C++, I do something similar

Foo::Foo( int bar )
: m_This(0)
, m_That(bar)
{
}

I don't know why I've adopted this... no, that's not quite right - I've adopted it because I perceive that it makes my life easier.  I haven't identified the source of that perception, and whether it has any validity.

Danil
Friday, May 23, 2003

occasionally, if appropriate, I'll go ahead and group related arguments on a single line:

void function_style_3prime
(
  int x, int y, /* x,y coordinates */
  int another_argument,  /* etc */
  int another_argument2,
  int another_argument3
)
{
/* do something */
}

I can see the advantage in debugging of style 4, it's like a visual equivalent of the trick

if (0==x)
{
/* do something */
}

but it's so ugly I wouldn't use it.

Also, sometimes needing lots of parameters for functions is a sign you need to be thinking about your design.

Brent
Friday, May 23, 2003

For me, commas in front gets:

-0.5 disadvantage, confuses automatic code formatters, including IDE/editors.

-0.5 disadvantage, confuses other programmers

But then, I still refuse to force my equivalency tests to fit the form (constant == variable) based on the fact that it is Just Wrong and saves you from something a decent compiler can warn you about anyway using other context clues, so YMMV.

George McBay
Friday, May 23, 2003

Oh, and for the record, after 8 years I've never "evolved" past FuncStyle1().  Personally I document the arguments in comments before the actual function declaration/definition. 

And -- especially with OO/C++/Java -- I find that if you're passing THAT many arguments to a function, your design is probably suspect to begin with.

George McBay
Friday, May 23, 2003

Readability is the key. I prefer all parameters on the same line as long as the line is not too long. Usually that means inside of the editor window.

When the line is too long, I prefer to break it up with one parameter per line, starting at the declaration line:

void myFunction(int a,
                          int b,
                          int c) {
  // implementation
}

(with monospace fonts, all parameter are nicely aligned)

Thomas Eyde
Friday, May 23, 2003

Function parameters?  Why the heck should I use those?  Global variables all the way baby!

Guy Incognito
Friday, May 23, 2003

All those people who give job candidates paper tests, take careful note: here is another highly relevant question you can give them.

Do they lay out their function declarations in the correct, approved way?

This will make it much easier for you to pretend you are a superior development group who only hires the best.

.
Friday, May 23, 2003

Hey "."

Be carefull what you say.....  some corporations are more interested in how well you "conform" instead of "think"!

Heston Holtmann
Friday, May 23, 2003

I can see putting the commas up front for things like extremely complicated SQL queries where each selected column is a big expression (guilty here), and I guess the same could be true if you were doing a really heinous function call with huge expressions.  Otherwise, it just strikes me as odd.

Then again, The way one guy did it above looks kind of cool, because you have all the ( , , , ) aligned on one column clearly outlining where the block begins and ends.  With that logic, though, you may as well start writing code blocks like this:

{ do()
; stuff()
; here()
; }

which stinks.

Keith Wright
Saturday, May 24, 2003

I didn't like #4 too much until I saw Danil's funkadelic variant.

It's cool. I'm switching!

Dennis Atkins
Saturday, May 24, 2003

Oh yeah! Oh yeah! Yeah baby!

I just changed 27 header files and I've never been happier!

Not just function declaration but all by pesky enum typedefs as well. There it's erally nice since the first enum is usually the special one that has a =1 or such tailing its name.

Danil's Variant is symmetrical, it's elegant, it's beautiful and it's oh so sexy!

Every line lines up now! Oh the joy! The rapturous ectasy!

Hearken! Danil's Variant is the One True Way!!!!

Dennis Atkins
Saturday, May 24, 2003

>{ do()
>; stuff()
>; here()
>; }

Listen not to the words of the devil!
Sets of statements differ from lists. Lists endeth not with the separator, whereas verily all Statements must end with the semicolon.

Similar these things are not! Apply Danil's Variant where it maketh sense and applieth not the variant to those realms in which it fitteth not.

Follow the Way of Truth and the code which thoust create shall reward thee.

Dennis Atkins
Saturday, May 24, 2003

You're a muppet, Atkins!

Thanks. I haven't had a good chuckle for a while.

Justin
Saturday, May 24, 2003

My own cult!  Tax exempt status, here I come....

Danil
Saturday, May 24, 2003

I notice outdentation bigotry at work...

Simon Lucy
Saturday, May 24, 2003

I like and use Danil's variant.

I have used all styles but after 18 years in business I find Danil's FuncStyle4 code most easiest to maintain. Especially in groups where many programmers work on the same code.

You never miss any commas, you always see all parameters, end of line comments don't interfere with commas, you just copy-&-paste line to get parameter from one func to the other...

nobody you know
Sunday, May 25, 2003

The convenience of cut-and-pasting as an argument for using certain style? That's lame.

Copy-and-paste function should be disabled in a programmer's editor.

Once again,  readability is the key. This is why the 4th style is BAD.

IMnsHO
Sunday, May 25, 2003

I find Danil's variant to be the most readible of all the styles.

so there
Sunday, May 25, 2003

Of course, it's a matter of taste. However, I don't see how placing punctuation marks in front can improve readability(unless you're programming in Perl).

Have you ever seen this style used in a (good) book on programming? I have not.

IMnsHO
Sunday, May 25, 2003

Books follow practice not the other way around.

In other words, better practices are adopted first, then they make their ways into books.

I converted because I tried it out on some code and saw that it was easier to read and work with. Sure, it took three minutes to get used to but now that I am used to it I see how it is much better in all its dimensions.

Speaking of dimensions, it makes the code more two-dimensional, more packed with meaning.

Things line up in a way they weren't lined up before.

Suddenly I don't have to use the scroll bars as much.

Suddenly I can instantly see typos.

Suddenly move parameters around is less likely to generate errors and requires less mental energy; it's just a mechanical operation now instead of a technical one.

Suddenly, commas are a formatting feature as well as being a syntactical one.

Behold - enums, initialization lists, and parameter lists are no longer unstructured but are graphical objects with a left edge and a top edge.

Behold - the code is cleaner.

Dennis Atkins
Monday, May 26, 2003

I tend to use different styles depending on the length of variable names and number of parameters,

function foo (s : string):number;
begin
  {do something}
  result:=0;
end;

wheras if I have

procedure DoSomethingThatIsLongerNamed(foo : String;
                                                                    bar:  String;
                                      SomeAwfullyLongName: Integer);

This to avoid horizontal scrolling to read the code.

Patrik
Monday, May 26, 2003

I started using the commas (and other operators) at the start of the line when fiddling with SQL statements. E.g.,

select field1
, field2
, field3
, field4
from table5
where field6 = 1
and field7 = 'WHATEVER'
and field8 like '%WHERE'S THE INDEX\?%'

If I wanted to comment out one of the conditions, I'd just do

select field1
, field2
, field3
, field4
from table5
where field6 = 1
--and field7 = 'WHATEVER'
and field8 like '%WHERE'S THE INDEX\?%'

and I'd be ready to go.

It does bite back, sometimes, but not as often as the opposite alternative, which would be

select field1,
field2,
field3,
field4,
from table5
where field6 = 1 and
field7 = 'WHATEVER' and
field8 like '%WHERE'S THE INDEX\?%'


I've started using this in other code very recently. It has improved readibility for me, in that things stand out more easily. Could be because of the novelty, though, i.e., when I get used to seeing separators and operators at the start of the line, maybe they won't stand out anymore.

--
"Suravye ninto manshima taishite (Peace favor your sword)" (Shienaran salute)
"Life is a dream from which we all must wake before we can dream again" (Amys, Aiel Wise One)

Paulo Caetano
Tuesday, May 27, 2003

Personally, I use a style (for C++) that looks like

/** Comment for literate documentation system like Doxygen
* parameter 1 info
* parameter 2 info
* return value info
*/
return_type my_function(param1, param2)
{
...
}

All the doxygen commenting goes into the header (.h) file, while the source (.cpp) file contains only commenting pertaining to how the code implements its functionality. If you need to see what it does, there is html, hyperlinked documentation kept up to date (and enforced by the peer pressure of a whole bunch of people who get pissy if it isnt).

This seems to work fine in the group I am in.

regards, treefrog

treefrog
Tuesday, May 27, 2003

FuncStyle 4 means that you didn't design properly.  the only real reason to do it that way is so that adding and deleting items will not incur a syntax error, because deleting the last item always deletes the appropriate comma.  This is good for arrays, enum etc but bad for methods (see first sentence).

Gregor Brandt
Tuesday, May 27, 2003

A bit of a tangent: an explanation of a *general* case where putting operators at the beginning of subsequent lines is useful. The initial example is all about function declarations, and several folks mentioned using a variation in constructing SQL queries. There's a similar situation where I've found this style helps a great deal both in legibility and in avoiding subtle errors: string concatenation. In doing Web-oriented development, we often have to concatenate literals and variables.

This:

var foo = "";
foo = "Value1 is: " +
    $val1 +
    " and Value2 is: " +
    $val2 +
    ".\n";

becomes:

var foo = "";
foo = "Value1 is: "
    + $val1 +
    + " and Value2 is: " +
    + $val2 +
    + ".\n"
;

all of a sudden, and especially if the chunks are long (e.g. have some embedded HTML), it's crystal-clear we're building up a string, and it's easy to shuffle the parts around, or insert a new part, without breaking the concatenation.

Another syntax, a real-world example:

Before:
<?php echo '<a href="' .
      href_link(FILENAME_DEFAULT) .
      '">' .
      image_button('button_continue.gif', IMAGE_BUTTON_CONTINUE) .
      '</a>'; ?>
     
After:
<?php echo '<a href="'
      . href_link(FILENAME_DEFAULT)
      . '">'
      . image_button('button_continue.gif'
              , IMAGE_BUTTON_CONTINUE)
      . '</a>'
  ;
?>

I'm switching to this style where possible -- it's saving me a lot of time. It's a particularly useful exercise when refactoring code,  esp. someone else's -- it helps me understand what's being built when I re-order the concatenation operators.

Just my $0.02 ...

Val Cohen
Wednesday, May 28, 2003

Hey Gregor...

"FuncStyle 4 means that you didn't design properly"

Hmm.. I moved all my comma's from the front to the back like FuncStyle 3, but the design didn't seem to improve in any way?

Heston Holtmann
Friday, May 30, 2003

*  Recent Topics

*  Fog Creek Home