TABs vs Spaces. The end of the debate.

May 14 2007

When writ­ing source code, indent­ing is very impor­tant. Hav­ing a neat and clean pro­gram­ming style, let alone a pre­cise and uni­form one, is prob­a­bly one of the most impor­tant keys when attach­ing exam­ple source code with a job appli­ca­tion. I was myself asked to show some of my source code in my last two inter­views. Nobody ever asked me to show any run­ning pro­gram that I had made, though. Won­der why? A lot can be under­stood about the author just by glanc­ing quickly at some source code.

Indent­ing makes the source code eas­ier to read for us human beings, whereas the com­piler doesn’t really care (except for some lan­guages, where inden­ta­tion applies as a syn­tax ele­ment). Even if you’re not a pro­gram­mer, you can see the dif­fer­ences here:

Com­piler friendly

Compiler readable

Badly indented

Badly indented

Prop­erly indented

Properly indented

There is, I guess, no ques­tion that the last one, labelled as “Prop­erly indented”, is the most read­able. Prob­lem arise, though, when peo­ple start won­der­ing what they should use as indent­ing char­ac­ter. Some pre­fer TABs, other pre­fer blank spaces. A TAB, the key on the left of the Q of most Qwerty key­boards, is a sin­gle char­ac­ter that a text edi­tor can rep­re­sent what­ever way it wants. This is usu­ally cus­tomiz­able by the user, of course, so she can decide that a TAB will be shown as 8 spaces, or 4, or 2.

You can hear all the time some­one claim­ing, in turn, that TABs are evil or that spaces are evil, but the truth is that none is wrong, as long as you can indent.

I’ll use, as an exam­ple, a piece of source code taken from the ext3 mod­ule of the Linux ker­nel. The Linux pro­gram­ming guide­lines rec­om­mend using TABs for indent­ing, and that they should be 8 spaces wide. Let’s have a look at some code.

8-space TAB

8-space.jpg

4-space TAB

4-space.jpg

2-space TAB

2-space.jpg

As you can see, the orig­i­nal intent of the author, was to have the vari­able names aligned. But that align­ment gets screwed up as soon as a reader has a dif­fer­ent space-size for her TABs. What’s wrong there? Let’s use a very use­ful Vim tip: the :set list command.

:set list
set-list.jpg

This way, we can actu­ally see the TABs, as “>——-”. Of course there will be less dashes if part of the TAB area is occu­pied by some text. So, can you see what’s wrong with that? The author of that source code is using TABs not only for indent­ing, but also for align­ing! That way his align­ment gets messed up when some­body uses a dif­fer­ent TAB size. The solu­tion of this prob­lem is to sim­ply just use what ever you want for indent­ing, but use spaces for align­ing. Indent­ing must only be that left mar­gin that you give to some lines, but it’s not to be con­fused with align­ment. If the author of that source code had used TABs at the begin­ning of the lines, but just blank spaces between the type and the name of the vari­ables, his code would be as he meant it what­ever indent­ing style one’s edi­tor would use.

So, in the end, it doesn’t mat­ter whether you use TABs or space, for indent­ing, as long as you use just spaces for align­ing.

Use­ful Vim/Emacs tip

I like spaces, and add the fol­low­ing to the end of all of my source files:

/*
Local Variables:
mode:c++
c-basic-offset:2
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
c-tabs-mode:nil
End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=2:tabstop=8:softtabstop=2

This way, if the reader uses Vim or Emacs (and maybe also gedit), her set­tings will be tem­porar­ily over­rid­den by mine, so, if she’s going to change my code, there are lit­tle chances that she’ll mess up my indenting.

The :set line options I use are the following:

set listchars=tab:>-,eol:$,trail:.,extends:#

It helps me to also spot trail­ing spaces. I rec­om­mend every­body to use the :set list, as it will pre­vent you to acci­den­tally mess up other’s indentation.

Tags:

19 responses so far

  1. But, if you are using a non fixed font to pro­gram –yes that kind of per­verts exists– using spaces to align is not cor­rect! You should use tabs!
    You can not win the debate. Use what­ever you want. I’m a tab boy, but it seems the space boys are more than us, so if you con­sider to share code you should use spaces.

  2. @ educhana, com­ment #1

    Hi,
    you see, the point is not being a tab or a spaces boy. The point is indent­ing, rather than align­ing, as peo­ple often do. I don’t care if you use tabs or spaces, as long as you use them to indent. To align, just use spaces.
    As for the non fixed fonts when pro­gram­ming, let the fools rot. I mean seri­ously, you can’t be a seri­ous pro­gram­mer if you non-fixed font!
    Any­way, thanks for the comment.

  3. @educhana: Umm, if you’re using tabs for align­ment and you switch from one pro­por­tional font to another, it MAY still break your alignment.

    Elas­tic tabs need to be stan­dard­ized!
    http://nickgravgaard.com/elastictabstops/

  4. To align, just use spaces.As for the non fixed fonts when pro­gram­ming, let the fools rot.

    Why are you “align­ing” some­thing after the first non-space char­ac­ter? You’re just ask­ing for trou­ble, espe­cially with non-fixed fonts. Plus what auto­matic code for­mat­ters under­stand this aligning?

    Just put the type, space, and then vari­able name.

  5. @BlogReader, com­ment #4

    I’m not align­ing, that piece of code comes from the linux ker­nel, and that style is used a lot. Non-fixed fonts… who uses them for pro­gram­ming, and why didn’t any­body tell them that it’s a bad habit?

  6. “… his code would be as he meant it what­ever indent­ing style one’s edi­tor would use.”

    The above is only true if the aligned text does not span dif­fer­ent lev­els of inden­ta­tion. This is the real rea­son why tabs are evil (for some users, in some situations).

    For those of us who think that visual pre­sen­ta­tion of the source can be impor­tant to under­stand­ing its seman­tic con­tent, spaces and fixed with fonts are the way to go.

    Cheers,
    Nick.

  7. I’m a text edi­tor devel­oper. And noth­ing is more repug­nant to me than see­ing peo­ple use spaces for inden­ta­tion. Apart from the fact that it makes all text pro­cess­ing oper­a­tions dif­fi­cult, the most annoy­ing thing about spaces is that it dis­obeys the inden­ta­tion pref­er­ences of users. I’ve rewrit­ing in detail about this on my blog.

    http://mystilleef.blogspot.com/2006/11/indentation-with-spaces-considered.html

    PLEASE use tabs for inden­ta­tion. For usabil­ity and acces­si­bil­ity pur­poses. If you don’t care about these or you don’t care about the pref­er­ences of peo­ple read­ing your code, then use spaces.

    Cheers

  8. @mystilleef, com­ment #7

    Hi. The pur­pose of this arti­cle wasn’t to pro­mote spaces over tabs. I’m ok with both. The only prob­lem is that tabs must not be used for align­ing, like in the vari­ables of the struct men­tioned in the article.

  9. I’m a tab per­son myself. But spaces has won out. Con­form or die.

    Long live spaces.

  10. I was think­ing of writ­ing an arti­cle on that … but there, you’ve said it all.

    Many coders I see around me still don’t get the dif­fer­ence between the uses of tab and space.

    Any peo­ple advo­cat­ing the use of one over the other, or point­ing out a fan­ta­sized short­com­ing of the “tab method” (includ­ing Nick West­gate) have still not got it and are a waste of office space ! ;oP

  11. I totally agree with the ari­cles view on using spaces for align­ment, and have an Emacs ques­tion: Since I want to use tabs for inden­ta­tion (so peo­ple can view it as they want) and spaces for my align­ment, it would be great if the auto-indent (press­ing ) func­tion­al­ity used tabs, and press­ing C-q pro­duced spaces. But the vari­able ‘indent-tabs-mode’ that switches spaces/tabs-behaviour, unfor­tu­nately changes it for BOTH sit­u­a­tions so that I can’t mix the styles as I want. What do to, what to do…?

  12. Nick West­gate (#6), you totally missed the point. The arti­cle explic­itly states that tabs should not be used for align­ment. YOU draw the con­clu­sion that tabs are there­fore evil, and spaces should be used, dis­re­gard­ing the arti­cles state­ment that for indent­ing tabs vs. spaces is a use­less dis­cus­sion nobody can win.

    So to con­clude, once again, don’t use tabs for alig­ment. For indent­ing use tabs or spaces. Period.

  13. Mike (#16), you got the point com­pletely. :)

  14. I like using tabs for inden­ta­tion because it allows mul­ti­ple edit­ing the same code to use what­ever scale of inden­ta­tion that they want, assum­ing they’re using an edi­tor that allows them to set the width of tabs. It just seems more friendly, since you don’t forge every­one read­ing your code into the same inden­ta­tion depth as you use.

    Obvi­ously, I use spaces for alignment.

  15. Ste­fan Persson,

    to have Emacs use tabs for inden­ta­tion and spaces every­where else, you can make the inden­ta­tion off­set an alias of the tab width, set ‘indent-tabs-mode’ to ‘nil’, and then write a wrap-around defad­vice for the inden­ta­tion func­tion that shad­ows the global value. E.g., for CC Mode:

    (def­var­alias ‘c-basic-offset ‘tab-width)
    (setq-default indent-tabs-mode nil)
    (defad­vice c-indent-line (around intelligent-tabs acti­vate)
    (let ((indent-tabs-mode t)
    (tab-width fill-column)
    (c-basic-offset fill-column))
    ad-do-it))

    The defad­vice also sees to that con­tin­u­a­tion lines are indented with a tab width-invariant mix­ture of tabs and spaces. For details, see http://www.emacswiki.org/emacs/IntelligentTabs .

  16. Finally, some­one with com­mon sense! I am a tab cadet for inden­ta­tion, but I pre­fer spaces for align­ing other parts of the line on those occa­sions when align­ment helps readability.

    An even bet­ter approach would be “elas­tic tab­stops” — basi­cally, use tabs as in a tab-separated data file, and the edi­tor can dynam­i­cally align the columns. Imag­ine you decide to add a vari­able that’s 3 char­ac­ters longer than the former-longest. No need to go back and adjust the spac­ing for the other 15 lines; the edi­tor takes care of pre­sen­ta­tion. Unfor­tu­nately, none of the good edi­tors have this option (yet?).

  17. White­space standards…

    When writ­ing code, it is good to be con­sis­tent about how you use white­space. When col­lab­o­rat­ing with oth­ers, it can actu­ally be detri­men­tal to your group’s pro­duc­tiv­ity if there is a mix of sys­tems, so the sen­si­ble thing is to pick a stan­dard ea…

  18. Has it ever occured to peo­ple that per­haps the prob­lem is that source code is saved as text files? Per­haps this aspect of pro­gram­ming needs to step out of the dark ages and into a mod­ern light. Why not have a new class of source code edi­tors that save every­thing as XML? The notion to inden­ta­tion and align­ment can sim­ply be set as user pref­er­ences in the edi­tor and not per­sisted in the source file itself. The for­mat­ting of the code should be more about the pref­er­ences of the indi­vid­ual pro­gram­mer and not any­thing to do with the source code itself. Two dif­fer­ent pro­gram­mers could view the same source code, but it is arranged in two totally dif­fer­ent ways to suit each pro­gram­mer dif­fer­ently. After all, to the com­piler the tabs and spaces are mostly mean­ing­less unless inside of a lit­eral piece of data.

    If the source code was actu­ally an XML doc­u­ment you could embed pic­tures and dia­grams in the actual file instead of rely­ing always on pure text based com­ments with lim­ited ASCII art. You could embed code review com­ments, revi­sion infor­ma­tion in a way that doesn’t clut­ter up the code.

    Don’t pick a side in this debate. Sim­ply elim­i­nate the need for the debate…

  19. Per­haps you should adapt your state­ment:
    “So, in the end, it doesn’t mat­ter whether you use TABs or space, for indent­ing, as long as you use just spaces for align­ing.” Add:
    “If you have decided to use TABs or spaces for indent­ing: use it con­se­quently.“
    Because if you mix it, you will have prob­lems with the indent if some­one else changes the tab width in his editor.

Leave a Reply