diff --git a/.agents/AGENTS.md b/.agents/AGENTS.md index 99ca7bff715ea..9e06b2f7c95db 100644 --- a/.agents/AGENTS.md +++ b/.agents/AGENTS.md @@ -44,3 +44,42 @@ MetricType(HasSubstr("outstanding_rpcs")), HasMetricLabel("channel_pool_lb_policy", Eq("RANDOM_TWO_LEAST_USED"))))); ``` + +## Type Deduction and `auto` Guidelines (Abseil Tip #232) + +Follow [Abseil Tip of the Week #232](https://abseil.io/tips/232) and the Google +C++ Style Guide: use `auto` only if it makes code clearer or safer, not merely +to avoid typing an explicit type. + +- **Range-Based `for` Loops Over Maps and Associative Containers:** + - Use `auto` with structured bindings (`for (auto const& [key, value] : map)`) + when iterating over `std::map`, `absl::flat_hash_map`, protobuf maps (e.g., + `metadata()`, `labels()`), and JSON `.items()`. + - *Why:* Iterating with `std::pair` triggers implicit conversions + and unintentional deep copies because map elements are + `std::pair`. Structured bindings eliminate this hazard and + remove `kv.first` / `kv.second` noise. +- **Standard Factory Functions:** + - Use `auto` when the type is explicitly specified on the RHS with standard + factory functions (e.g., `auto client = std::make_shared();`, + `auto ptr = std::make_unique(...);`). +- **Iterators:** + - Use `auto` for iterator variables when the container type is clearly + declared in the local scope (`auto it = local_vec.begin();`). + - When the container is not local (e.g., a class member variable), either + spell out the iterator type or explicitly bind the dereferenced element type + (e.g., `ElementType const& elem = *it;`). +- **Spell Out Domain Types, Protobufs, and Return Values:** + - Do not use `auto` where it obscures domain types, protobuf messages, or + function return types (e.g., avoid `auto actual = client.InsertObject(...)`; + use `StatusOr actual = ...`). + - Do not use `auto` for nested protobuf access (e.g., avoid + `auto const& field = proto.nested().field()`; spell out the protobuf/string + type). +- **Avoid `auto` for Primitive / Numeric Types:** + - Use explicit types (`std::size_t`, `std::int64_t`, `std::uint32_t`, etc.) + instead of bare `auto` initialized with integer literals. +- **Explicit Semantics (`const`, `&`, `*`):** + - When a reference or pointer is intended, always explicitly qualify as + `auto const&`, `auto&`, or `auto*` to prevent accidental copies (since bare + `auto` deduces by value) and to make ownership and mutability unambiguous. diff --git a/.gemini/styleguide.md b/.gemini/styleguide.md index cd57803d749c2..6d7e57dfc3e68 100644 --- a/.gemini/styleguide.md +++ b/.gemini/styleguide.md @@ -72,6 +72,34 @@ When reviewing or generating code, apply rigorous scrutiny: - **Documentation:** Document all public items in libraries with Doxygen style comments using `///`. +## Type Deduction (`auto`) + +Apply the type deduction rules from +[Abseil Tip #232](https://abseil.io/tips/232) and the Google C++ Style Guide +during code reviews: + +- **Require Structured Bindings in Map Loops:** In range-based `for` loops over + maps, protobuf maps, and JSON `.items()`, require `auto` with structured + bindings (e.g., `for (auto const& [key, value] : map)`). Flag loops that use + `std::pair` or trigger implicit copy conversions. +- **Factory Functions:** Allow `auto` when the type is explicitly written on the + RHS (e.g., `auto ptr = std::make_unique(...);`, + `auto client = std::make_shared(...);`). +- **Iterators:** Allow `auto` for iterators only when the container type is + locally visible. When iterating over non-local/member containers, require + explicitly typed dereferences (e.g., `ElementType const& elem = *it;`). +- **Reject Obscured Domain & Return Types:** Flag and reject `auto` when it + hides `StatusOr`, domain objects, protobuf messages/fields, or function + return types (e.g., demand + `StatusOr actual = client.InsertObject(...)` instead of + `auto actual = ...`). +- **Disallow `auto` for Primitives:** Require explicit numeric and scalar types + (`std::size_t`, `std::int64_t`, `bool`, etc.) rather than deducing them from + literals. +- **Enforce Explicit Qualifiers:** Ensure `auto` is explicitly qualified with + `const`, reference (`&`), or pointer (`*`) (e.g., `auto const&`, `auto&`, + `auto*`) to prevent unintended copies or ambiguous mutability. + ## Google Cloud SDK Specifics - **Generated Code:** Do not edit files with a "Generated by the Codegen C++