<div dir="ltr">I pretty much agree with this.  However, I'll mention that the contentious use case in the code review came from something that is technically the second form, the problem is just that it wasn't obvious.  Specifically, the line was this:<div><br></div><div>auto NodeKind = ASTNodeKind::getFromNodeKind<DerivedT>();</div><div><br></div><div>Technically this is no different than saying </div><div><br></div><div>auto file = File::open(open_flags);</div><div><br></div><div>The return type is File, so it should fall under always auto.  The objection that arose was with the ASTNodeKind line that it wasn't obvious to someone unfamiliar with that code that it was such a function.  For starters, one might think the return type is something like ASTNode, not ASTNodeKind.  Additionally, because the factory function takes a template argument, it's not clear if the return type also depends on that template argument.  Is it an ASTNode<DerivedT>, or ASTNodeKind<DerivedT>, or maybe just a unique_ptr<DerivedT>.  </div><div><br></div><div>So at the risk of stating the obvious -- just having the return type spelled out on the RHS of the equal sign is not sufficient, it must also be obvious that the return type is spelled out on the RHS of the equal sign.  With something like dynamic_cast<T>, etc it is, because these are well-established language constructs.  But with user-defined types, not always.</div><div><br></div><div>So this is where I agree with Chandler, that a case like this is borderline and there's some judgement on the part of the person looking at the code review.</div><div><br><div><div class="gmail_quote"><div dir="ltr">On Tue, Dec 4, 2018 at 11:22 AM Herb Sutter via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div lang="EN-US" link="blue" vlink="purple"><div class="m_7216271894422422661WordSection1"><p class="MsoNormal">> > Perhaps the rule came be rewritten more generally, as in “auto should generally only be<u></u><u></u></p><p class="MsoNormal">> > used when the inferred type is obvious from context,<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p></div></div><div lang="EN-US" link="blue" vlink="purple"><div class="m_7216271894422422661WordSection1"><p class="MsoNormal">> I still think this is the correct core rule: there needs to be *some* reason why the type is<u></u><u></u></p></div></div><div lang="EN-US" link="blue" vlink="purple"><div class="m_7216271894422422661WordSection1"><p class="MsoNormal">> contextually obvious. And honestly, I'm very happy erring on the side of writing out the<u></u><u></u></p><p class="MsoNormal">> type name. I think people are too eager to use `auto` because it is easy to write but it<u></u><u></u></p><p class="MsoNormal">> makes the types substantially harder for the reader to understand.<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p></div></div><div lang="EN-US" link="blue" vlink="purple"><div class="m_7216271894422422661WordSection1"><p class="MsoNormal">FWIW, auto != infer. Since AAA* was mentioned and I wrote that, I just wanted to clarify never intended it to mean to always use auto for type inference.<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">I’ve always tried to carefully say there are two forms, but people seem to fixate on the first one:<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">              auto x = non-cast-expr; // inferred type<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">              auto x = type( expr );      // explicit type – includes dynamic_cast<>, {} vs () syntax, etc.<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">The advice to “always auto” includes the second form, and so you can always use auto without loss of readability because it’s not in tension with stating an explicit type. FAQ: Why write the second form “auto x = type( expr );” instead of just the traditional “type x( expr );”? For several reasons, perhaps the most important being that with “auto” you can never forget to initialize a variable because the = is mandatory. There are also other advantages, such as no vexing parse, consistency with other left-to-right modern declarations such as using, and others; all these advantages apply to both forms above, you get them just by starting with “auto.”<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">But again this is just a “FWIW,” I’m just clarifying, not trying to campaign. The main thing for any team is to adopt a style that people are happy to live with.<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">Herb<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal">* Actually AA these days. Thanks, Richard, both for promoting guaranteed copy elision and for pointing out that it eliminates the first A! Auto style is now easy and efficient to use with all types, even std::array and lock_guard. Insert gratuitous battery size joke here about how AA is an upgrade, carries more charge, etc.<u></u><u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal"><u></u> <u></u></p><p class="MsoNormal"><u></u> <u></u></p><div style="border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt"><div><div style="border:none;border-top:solid #e1e1e1 1.0pt;padding:3.0pt 0in 0in 0in"><p class="MsoNormal"><b>From:</b> cfe-dev <<a href="mailto:cfe-dev-bounces@lists.llvm.org" target="_blank">cfe-dev-bounces@lists.llvm.org</a>> <b>On Behalf Of </b>Chandler Carruth via cfe-dev<br><b>Sent:</b> Tuesday, December 4, 2018 5:02 AM<br><b>To:</b> Chris Lattner <<a href="mailto:clattner@nondot.org" target="_blank">clattner@nondot.org</a>><br><b>Cc:</b> <a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>; <a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>; Stephen Kelly <<a href="mailto:steveire@gmail.com" target="_blank">steveire@gmail.com</a>><br><b>Subject:</b> Re: [cfe-dev] [llvm-dev] RFC: Modernizing our use of auto<u></u><u></u></p></div></div></div></div></div><div lang="EN-US" link="blue" vlink="purple"><div class="m_7216271894422422661WordSection1"><div style="border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt"><p class="MsoNormal"><u></u> <u></u></p><div><div><div><p class="MsoNormal">On Wed, Nov 28, 2018 at 6:25 PM Chris Lattner via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>> wrote:<u></u><u></u></p></div><blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in"><p class="MsoNormal">Generally no IMO, because the cases that produce optional are not obvious.<u></u><u></u></p></blockquote><div><p class="MsoNormal"><u></u> <u></u></p></div><div><p class="MsoNormal">Just to say, +1 from me too.<u></u><u></u></p></div><div><p class="MsoNormal"> <u></u><u></u></p></div><blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in"><p class="MsoNormal"><br>> * Can we use auto in c++14 lambda arguments with llvm::find_if(C, [](const auto& i) { ... }) for example?<br>> * We need to use auto for structured bindings, if those are used.<br><br>These both get into “yes, if the type is contextually obvious”.  I’m not sure how to specify this though.<br><br>Perhaps the rule came be rewritten more generally, as in “auto should generally only be used when the inferred type is obvious from context, e.g. as a result of a cast like dyn_cast or as a result of constructing a value with a constructor containing a type name.”?<u></u><u></u></p></blockquote><div><p class="MsoNormal"><u></u> <u></u></p></div><div><p class="MsoNormal">Strongly agree.<u></u><u></u></p></div><div><p class="MsoNormal"><u></u> <u></u></p></div><div><p class="MsoNormal">I understand it may not be as precise and unambiguous as people would like, I still think this is the correct core rule: there needs to be *some* reason why the type is contextually obvious.<u></u><u></u></p></div><div><p class="MsoNormal"><u></u> <u></u></p></div><div><p class="MsoNormal">And honestly, I'm very happy erring on the side of writing out the type name. I think people are too eager to use `auto` because it is easy to write but it makes the types substantially harder for the reader to understand.<u></u><u></u></p></div><div><p class="MsoNormal"><u></u> <u></u></p></div><blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in"><p class="MsoNormal">> In the case that came up in review for me, the code I submitted is<br>> <br>> template <typename BaseT, typename DerivedT><br>> void registerIfNodeMatcher(...) {<br>>  auto NodeKind = ASTNodeKind::getFromNodeKind<DerivedT>();<br>>  if (!NodeKind.isNone())<br>>    NodeCtors[NodeKind] = std::make_pair(MatcherName, Descriptor);<br>> }<br>> <br>> but it was rejected as unreadable and I was given a link to the coding guidelines.<br><br>I agree, this seems overly strict.<u></u><u></u></p></blockquote><div><p class="MsoNormal"><u></u> <u></u></p></div><div><p class="MsoNormal">I mean maybe. But looking at the example, I don't have a clue what type `NodeKind` is. I think this is borderline, and I think its fine to be somewhat subjective based on the reviewer that is more familiar with the code and APIs in question.<u></u><u></u></p></div><div><p class="MsoNormal"> <u></u><u></u></p></div><blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in"><p class="MsoNormal">> I'd also like to update them so that<br>> <br>> llvm::Optional<std::pair<std::string, MatcherCtor>><br>> getNodeConstructorType(ASTNodeKind targetType) {<br>>  auto const &ctors = RegistryData->nodeConstructors();<br>>  auto it = llvm::find_if(<br>>      ctors, [targetType](const NodeConstructorMap::value_type &ctor) {<br>>        return ctor.first.isSame(targetType);<br>>      });<br>>  if (it == ctors.end())<br>>    return llvm::None;<br>>  return it->second;<br>> }<br>> <br>> is acceptable. The `auto it` is already acceptable, but the `auto const& ctors` depends on an interpretation of the guideline and was rejected in the review I submitted.<br><br>This seems like a step too far from me.  I don’t know what nodeConstructors is here at all, and you’ve erased all type information about what you’re dealing with.<u></u><u></u></p></blockquote><div><p class="MsoNormal"><u></u> <u></u></p></div><div><p class="MsoNormal">Strongly agree. The `auto it` continues to seem fine, but the `ctors` here seems super confusing to leave off all type information.<u></u><u></u></p></div></div></div></div></div></div>_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div></div></div></div>