[webkit-dev] [webkit-reviewers] usage of auto

Geoffrey Garen ggaren at apple.com
Wed Jan 11 10:55:35 PST 2017


I’m open to auto, but skeptical.

(1) Research-ability. I read a lot of code that is new to me, that I have never written. I find type statements to be useful as documentation for where to look for more information about how data structures and algorithms relate to each other. Traversing a tree or list of data structures by type name while reading code is a common task for me. But I can’t select and search for auto, auto*, or auto&.

(2) Mechanics. It’s totally true that if you loop over one collection and put the values into another collection, subject to some filter, the types involved aren’t really interesting to reviewing the filter. But if you want to review low-level mechanics like object lifetime and thread safety, suddenly the types are really important. I think the “I changed RefPtr to auto and then crashed” examples in this thread are about mechanics.

I find it strange that, as JavaScript authors adopt tools like TypeScript because they find type-less programming to be unmaintainable, C++ authors move toward type-less programming. Perhaps the grass is always greener on the other side. Or perhaps we can strike a balance and put types where they help us.

Two arguments made in favor of auto don’t fully convince me:

(1) You were always able to hide the types of certain expressions. 

I’m hoping the point of this argument is not to say “in for a penny, in for a pound”, but rather to raise our awareness that we’ve been OK with certain type-less expressions all along. I agree: I'm OK with hiding types in some places, especially if surrounding code already provides some kind of type foothold.

At the same time, I sometimes break expressions into statements to improve clarity and research-ability or to achieve certain mechanics.

Maybe this answers Darin’s question:

> Here’s one thing to consider: Why is it important to see the type of foundSource->value, but not important to see the type of shifts.take(source)? In both cases they need to be Vector<ShufflePair>.

In the cited code, ‘shifts’ is declared as HashMap<Arg, Vector<ShufflePair>>, and HashMap ’take' is well understood to return its value type, so no further comment about type is necessary for me on this line.

Following this logic, I might be OK with eliding the type of foundSource->value. But we’re starting to reach a limit. Each time we do this we create an auto link in the type chain. If I have to trace back three autos deep in order to understand a type, I’m gonna have a bad time. Each type declaration is a stopping point for research. Therefore, I don’t prefer the fully auto version of this code.

Following this logic, I would be OK with const auto& a little later in this algorithm:

>             bool isRotate = false;
>             for (const ShufflePair& pair : currentPairs) {
>                 if (pair.dst() == originalSrc) {
>                     isRotate = true;
>                     break;
>                 }
>             }

Might as well use const auto& for ‘pair’: The type of currentPairs is well-documented locally. If currentPairs were a data member, and not declared in the same screenful of code, I would want to write out a type for ‘pair’. Otherwise, I would have to open another file to understand this line.

But somebody said we don’t like const auto&? Is this a gotcha somehow?

(2) You can’t be sure of the stated type, since a type conversion may have happened.

Knowing that a value is equivalent to a certain type still provides a foothold for research and understanding mechanics.

We only allow automatic type conversion when we consider types to be reasonably equivalent. We consider it bad style to convert willy-nilly, and we use the explicit keyword to avoid errant conversions. For example, we don’t allow RefPtr to automatically convert to raw pointer.

Geoff


More information about the webkit-dev mailing list