Richard Biener <richard.guent...@gmail.com> writes: > On Fri, May 15, 2020 at 10:30 AM Richard Sandiford > <richard.sandif...@arm.com> wrote: >> >> Richard Biener via Gcc-patches <gcc-patches@gcc.gnu.org> writes: >> > Note I think what's missing is some general blurb in our coding conventions >> > as to how much of C++11 we are supposed to use in non-infrastructure parts >> > of GCC (I expect things like hash-table.h to use more C++ features than, >> > say, tree-ssa-alias.c). >> >> I guess there are two aspects to that: >> >> - Are there any specific features we should avoid using at all? >> TBH I hope not. Trying to police this based on C++ feature sounds >> difficulty and might be counterproductive. >> >> IMO it should just (continue to) be based on principles like avoiding >> abstraction for abstraction's sake, and keeping compiler performance >> and code size in mind. Even tree-ssa-alias.c should be able to use >> any C++ feature if there's a justification. >> >> - Coding conventions for when features should be used. "auto" is an >> obvious one. Maybe also lambdas (which should help avoid the horrible >> "void *" callback parameters we have all over the place now). >> >> Maybe also guidelines to actively use certain features, e.g. >> >> - use "= default" where possible >> >> - prefer range-based for loops to macros >> >> - mark "operator bool()" conversions as explicit >> >> - use "override" where applicable >> >> (all obvious I guess), etc. > > I think the most important thing is that refactoring for the sake > of refactoring is bad iff it does not improve on consistency > throughout the code base. We should really try hard to use > C++ features consistently - this makes the code base easier > to understand.
Agreed. One of the reasons I'm keen to have something in the coding standards is that things became less consistent after the C->C++ switch. Maybe we should reconsider some of the existing coding standards too. E.g.: Define all members outside the class definition. That is, there are no function bodies or member initializers inside the class definition. isn't widely followed. That's a bit of a tangent though. (FTR, I've no attachment to the current conventions and didn't contribute anything to them. More consistency would be good though.) > We've moved more and more to stronly-typed data structures > so I'd not like to see 'auto' everywhere - it should be still > obvious what kind of objects we're working with where they > matter. IMHO they do not matter for example for iterators. > I don't care about the iterator type but about the type of > the object and the container. Also agreed. :-) How about this as a starting point: --------------------------------------------------------------- Use auto for: - the result of casts or other expressions that give the type explicitly. E.g.: if (auto *table = dyn_cast <rtx_jump_table_data *> (insn)) instead of: if (rtx_jump_table_data *table = dyn_cast <rtx_jump_table_data *> (insn)) - iterator types. E.g.: auto it = foo.begin (); instead of: foo_type::iterator it = foo.begin (); - expressions that provide an alternative view of something, when the expression is bound to a read-only temporary. E.g.: auto val1 = wi::to_wide (...); auto val2 = wi::uhwi (12, 16); instead of: wide_int val1 = wi::to_wide (...); wide_int val2 = wi::uhwi (12, 16); (Using "wide_int" is less efficient than using the natural type of the expression.) - the type of a lambda expression. E.g.: auto f = [] (int x) { return x + 1; }; Do not use auto otherwise. --------------------------------------------------------------- One thing I wondered about is whether we should encourage auto for normal integer results. It would avoid problems with values being silently truncated to a narrower type (e.g. HOST_WIDE_INT->int). On the other hand, that kind of truncation will still happen in things like function calls and member variable assignments. Using "auto" could also hide important signedness choices. So not using "auto" is probably better there... Richard