Consider this if clause, notice that it's without the brackets {}
around it, although some reviewers ask for putting {} around the if,
others remove it.
if (foo &&
bar &&
whatever)
DoSomething();
So should it be with or without the {} around it?
if
must always always have an accompanying brace.
--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-dev
The coding style stats that:
- Other formatting "rules" are not required, but are fairly common across Chrome code, and thus it's probably best to stick to them unless you have a reason not to. In particular, if existing code follows these styles, maintain them:
- Prefer (foo == 0) to (0 == foo)
1) It hampers readability. Nobody thinks that way. The reader has to
continually re-parse the intent.
2) We have compiler warnings for the (foo = NULL) case, and they are turned on.
--
Mike Pinkerton
Mac Weenie
pink...@google.com
I would like to know what is the con-sense about the following coding styles:
In general, curly braces are not required for single-line statements, but they are allowed if you like them; conditional or loop statements with complex conditions or statements may be more readable with curly braces. Some projects require that an if must always always have an accompanying brace.
Consider this if clause, notice that it's without the brackets {} around it, although some reviewers ask for putting {} around the if, others remove it.
if (foo &&
bar &&
whatever)
DoSomething();
So should it be with or without the {} around it?
Now consider the following if clause:
if (foo->Bar(
type)) {
DoSomething();
}
Notice that |type| is indented 4 spaces and the if clause has {} around it. Now I ask, the indentation is wrong? Shouldn't it have brackets around it?
Finally, what is the preferred why to retrieve an element from std::vector, either vector::at or vector::operator[]?
"The difference between this member function and member operator function operator[] is that vector::at signals if the requested position is out of range by throwing an out_of_range exception."
This isn't technically one of the requirements. Sometimes {} in this
case can help readability and you should do it. Other times its less
important and you can leave it off.
Brett
Have there even been arguments for always adding braces?
There’s this, there’s the “I have fewer decisions to make so I can
focus on what matters” point, and there’s “it makes adding statements
or otherwise maintaining the whole construct easier in the future”
point. I personally never experience the situation you bring up when
I’m writing code, but I see it all the time when debugging by
inserting printfs or LOGs at strategic decision points and wind up
having to insert braces all over the place. That really gets my goat.
Against “always require” is that it always gives you an extra line
vertically (but just one in an entire if/else if/else if/else sequence
given that we use cuddly “else,” so no big deal, right?,) and that the
opening brace would very infrequently bump a line past 80 characters
requiring creative reindenting.
I still think it ought to be a judgment call. I probably favor braces
in most cases, but I wouldn’t imagine writing a real shorty with
braces.
if (a < b)
r = -1;
else if (b > a)
r = 1;
else
r = 0;
if (a < b) {
r = -1;
} else if (b > a) {
r = 1;
} else {
r = 0;
}
Maybe it’s just what I’m accustomed to, but the former permeates my
brain more readily. (No, don’t write the above by nesting a ternary.)
I personally always use braces; I actually find the *lack* of braces
makes C/C++ conditionals harder to read, but that's probably from
force of habit. Back in the day when I wrote C code for a living at
Oracle, lack of braces in existing code frequently caused maintenance
problems for me (and others).
I particularly dislike it when people put the statement on the same
line as the conditional, braces or no:
if (foo) DoSomething();
The problems with this are that it's usually impossible to set a
breakpoint on DoSomething() (so that you only break when the condition
is true) [of course, you can do this with a watchpoint], and that it
makes it more important to get branch-level code coverage instead of
line-level (and line level is usually much easier to get).
That said, I am not arguing that we change the style guide.
-- Dirk
In general, braces are visually noisy, so the cost is not just vertical space, but also slight cognitive load.
and that it makes it difficult to tell if there’s something wrong with
foo or DoSomething() if all you’ve got is a backtrace from Breakpad.
Whether it’s right or not, debugging tools are much more capable at
the line level than they are at the expression level. The style guide
permits the above as a one-liner when it “enhances readability,” but
I’d say “never do it.”
On the other hand, if you’re in some big dispatcher-like thing
structured as a switch statement, I can see a much better argument for
putting each case on a single line if it’s a readability win.
The style guidepermits the above as a one-liner when it “enhances readability,”
Sadly, it’s tolerated.
http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml?showone=Conditionals#Conditionals
> Short conditional statements may be written on one line if this
> enhances readability. You may use this only when the line is brief and
> the statement does not use the else clause.
>
> if (x == kFoo) return new Foo();
> if (x == kBar) return new Bar();
If you know that your index is within the vector’s bounds, it doesn’t make a difference. If you haven’t checked the index: if it’s OK to crash (since we don’t handle exceptions) vector::at is fine. If it’s OK to do the wrong thing (read or write memory that doesn’t belong to the vector), operator[] is fine. I think that it’s usual to check the index, though.
Finally, what is the preferred why to retrieve an element from std::vector, either vector::at or vector::operator[]?"The difference between this member function and member operator function operator[] is that vector::at signals if the requested position is out of range by throwing an out_of_range exception."
I believe we do compile with -fno-exceptions. This makes any code
that throws simply print the exception and abort the program.
We can’t get rid of exceptions from portions of the C++ standard
library that we link against as a binary. “new char[-1]” will throw
std::bad_alloc regardless of whether you build your own code with
-fno-exceptions.
> Out of curiosity, do we compile with -fno-exceptions?
On Mac and Linux, for Chromium, yes. This isn’t necessarily consistent
across projects or platforms, though.
> If so, does this
> cause strange behavior when using vector::at on out of bounds elements?
You get an exception, and it’s unhandled, and the program aborts. In
GNU libstdc++, this exception is thrown from the binary portion of
libstdc++. This is std::__throw_out_of_range(const char*). This isn’t
particularly strange. It’s exactly the same thing as what happens when
exceptions are enabled, an exception is raised, and there isn’t a
“try” anywhere on the stack.
> I would think that the range check and using operator[] would be the
> preferred choice given the decision @ google to not use exceptions.
“Don’t use exceptions” is an oversimplification when we’re discussing
actual exception handling internals. It would be more accurate to
characterize the position as “never write throw or try; possibly build
with -fno-exceptions; accept that C++ exceptions might occur anyway;
accept that they will result in crashes.”
> Should choices like this be discussed in a STL-specific style guidelines of
> the C++ styleguide?
I doubt it. There are other documents where this discussion might be
appropriate. This isn’t really about style, it’s about how the C++
standard library works and how to use it. (It’s also exactly the sort
of thing that I suspect the kids have in mind when they say that C++
makes it too easy to shoot yourself in the foot.)
The tradeoff, when you’re not checking your indices, is between one
sort of bug (bad access, corruption or crash) and another (certain
crash, since we can’t write “catch.”) [] is prettier and
well-recognized. std::vector<>::at isn’t forbidden. We’re not going to
outlaw std::vector<>::operator[] either.
Bottom line? Check your indices.