Monday, July 17, 2006

Code Advice #10: Place brackets with the declaration type, not the name

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


(See intro for a background and caveats on these coding advice blog entries.)



The most important code style rule is that when you modify somebody else's code, you preserve the coding style in that file. Even when it hurts. The only thing worse than an "incorrectly" styled source file is an inconsistently styled one!



One of my coworkers writes Java code in a very C-inspired way. One of the habits I have difficulty with is the bracket placement for arrays. I thought I would dedicate a blog entry to this, because it occurs in many other code bases. A quick scan revealed a couple thousand matches in the JDK source code (which, granted, is a tiny fraction of the overall codebase).



Briefly stated, the correct way (as far as I'm concerned) to place brackets in an array declaration is with the type, not with the variable name. Therefore, this is okay:


int[] scores;

and this is not:

int scores[];



Here's a real-world example, from String.java:


@Deprecated
public String(byte ascii[], int hibyte, int offset, int count) {
checkBounds(ascii, offset, count);
char value[] = new char[count];
...

As you can see, there are two violations here - both in the parameter usage, and in the declaration
of local variable "value".



Most of you will probably just nod at this and move on, since it's what you're already doing. But if there's one thing I've noticed, it's that coding style blog posts always generate controversy - and that especially those of you doing it the Other Way are reluctant to change.



So, let me spend a couple of paragraphs arguing why you should place the brackets with the type name, not the variable name. The most obvious answer is that brackets-with-type is what by far most Java developers are using, so you should simply do it to make your code consistent with the accepted practice.



However, it does have some logical reasons too.



First, let's take a look at a method declaration that returns an array - this is java.util.Arrays.copyOf:


public static int[] copyOf(int[] original, int newLength) {

Notice how the brackets appear with the type declaration. You do not have the luxury of moving them to the end of the line, or even just past the variable name:

public static int copyOf[](int[] original, int newLength) { // WRONG!



Note that if you have code like this:


int[] a, b;

Here both a and b will be integer arrays. This is different than in C
where the similar

int* a, b;

would leave only a an array, and b a scalar!



Let me anticipate the objections. I can think of two advantages for placing brackets with variable names.
First, it's your only option if you want to mix and match plain and array declarations of a type in the
same statement:


int a, b[], c, d[];

However, we can dispense with this quickly: you should not compress declarations this way. Use a separate
statement for each.



The second objection, which I have some sympathy for, is that placing brackets with variable names
is consistent with the way array instances are used:


int foo[];
...
foo[i] = -1;

However, between declaration and usage we have the initialization, and the initialization uses the
typename with brackets:

int[] foo = new int[50];
foo[i] = -1;



An easy way to find violations of this coding style is to use Checkstyle. Note that while javac will
happily compile both declaration styles, the error message from checkstyle is:


Array brackets at illegal position.

I guess that's stretching the definition of "illegal" a bit (since the
Java Language Specification defines what is legal and what is not, and both forms are allowed). However, in my opinion it is good practice to place the brackets where most Java developers place them - with the typename in declarations.


6 comments:

  1. You are very brave to write blog entries on code style :) That said I'm a 100% with you. I used to use the int a[] notation, because I have taught so for whatever reason, and one day I just realized it was crap. To me it's very simple: an array is a type, therefore the brackets must be placed in the type part of the declaration.
    P.S: What about a JavaPosse dedicated to coding conventions? I can't wait to hear the listeners feedback about tabs vs spaces, about where to put the curly braces, etc. :)

    ReplyDelete
  2. Hi Tor, the book Code Complete covers a lot of this type of coding best practices. There's some good info online including some checklists (note: free registration is required).

    ReplyDelete
  3. Does anyone disagree? Of course, in C++ you have to do it the other way (int a[]). As a long time C/C++ programmer, I was very glad to see Java fix that.

    ReplyDelete
  4. I'm sure the other day I saw an example in the JDK of one method declaring parameters in both styles...

    ReplyDelete
  5. Spaces are of course the one and only true way to do indentation, after all the whole point of indentation is for the code to look exactly the same from one machine to another.
    I do sometimes pine for a 'super space' though. One programmer (lets call him Robert) might prefer 2 space indents, while the other (lets call him Rick) prefers 4 space indents. If only there was a 'super space' which the IDE would magically transform so Robert could see things the way he wanted to, and at the same time Rick could see things the way he preferred... and when Robert indents by hitting the space bare twice and Rick looks at the code his IDE will 'sneak in' the extra spaces without human intervention.
    Why should we tolerate this kind of behaviour form programmers? Surely they should just sit down and agree on exactly how the code should look? Let us lock Robert and Rick in a room until they agree. Sadly, it turns out that Robert uses Eclipse on a massive monitor with most of the screen area taken up by the multitude of Tabs which Eclipse offers for your convenience. And so Robert's code area is quite small, and he uses a four point font. (Seriously). Whereas Rick may prefer to code on 800x600 with large fonts on and bump his font size up to 14 and use lots of whitespace (his desk is messy, with everything spread out widely too... coincidence? I think not) because he is a visual/spatial thinker (and doesn't want eyestrain). Then Ronaldo enters the room, he has two monitors and doesn't even use Eclipse! The horror, the funky horror... will noone stop this travesty of justice?
    Although naturally code should always have one true appearance, with a defined font, font size, colour coding, number of columns etc. perhaps for the sake of our three combatants we should relax the requirement... let each one use his own setup that he prefers. Let us define 'super space' so that it allows us to take minor liberties with the appearance of the code, each according to his preferences.
    The 'super space' could do other things too... lets us say that we have code in two different programming languages inside the same file, and we want to make them look distinctive to make it easier to tell them apart... We could make one of them Courier and the other Arial or Times Roman. But those are proportional fonts, not monospaced like Courier. So a normal space is much smaller in those fonts than it needs to be for good indenting. 'Super space' to the rescue! Let's say that 'super space' can do the right thing here and indent as though it were monospaced. Also, the proportional characters don't quite line up properly... wouldn't it be nice if 'super space' could line things up properly regardless of what else is on the line?
    Then what would be really good is if 'super space' could let us get to the correct level of indentation a lot faster, it should be smart enough to increase or decrease with a single keystroke. I guess 'super space' would have to not be a keystroke, it would have to be something else like CTRL-Space, or that is probably taken already by various other functions. But there is no doubt some easy key combination not taken yet which could be used.*
    I know what you are thinking, that this would be really cool, but even the basic functions outlined above are actually extraordinarily difficult. Just thinking about dealing with proportional fonts and knowing where 'super spaces' have ended up on previous lines would be incredibly processor intensive, it would require some really over the top algorithms.
    *How about Ctrl-T Alt-A Ctrl-B, I don't think that is taken yet?

    ReplyDelete
  6. Hi
    I'm a big fan of code style discussions and made a small cartoon about it.
    Bye,
    Oliver

    ReplyDelete