@@ -2619,6 +2619,28 @@ <h3 id="Pass_By_Value">Pass by Value</h3>
26192619 < li > < a href ="https://stackoverflow.com/questions/10231349/are-the-days-of-passing-const-stdstring-as-a-parameter-over "> Stack Overflow: Are the days of passing const std::string& as a parameter over?</ a > </ li >
26202620</ ul >
26212621</ p >
2622+
2623+ < h4 id ="Pass_By_Value_Primitives "> Pass by Value: Primitives</ h4 >
2624+
2625+ < p > Prefer to pass primitives (e.g., < code > int</ code > or < code > double</ code > )
2626+ by value, not by const reference.</ p >
2627+
2628+ < p > The same goes for copyable types that are tantamount to primitives,
2629+ such as type-safe integers (e.g., < code > drake::TypeSafeIndex</ code > or
2630+ < code > drake::Identifier</ code > ) and thin wrappers
2631+ (e.g., < code > std::optional<double></ code > , because it's akin to a
2632+ pair of < code > (bool, double)</ code > ).
2633+
2634+ < p > Drake's
2635+ < a href ="/doxygen_cxx/group__default__scalars.html "> default scalars</ a >
2636+ (known conventionally as < code > <typename T></ code > ) are often thought
2637+ of as a < code > double</ code > because they denote a mathematical scalar,
2638+ but because scalar types other than < code > double</ code > are not primitives,
2639+ templated scalars should be passed as < code > const T&</ code > , not by value.</ p >
2640+
2641+ < p > See also < a href ="#Use_of_const "> Use of const</ a > for an explanation of
2642+ whether arguments passed by-value may be declared < code > const</ code > .</ p >
2643+
26222644</ div >
26232645
26242646< h3 id ="Friends "> Friends</ h3 >
@@ -2651,13 +2673,6 @@ <h3 id="Exceptions">Exceptions</h3>
26512673noted below.</ p >
26522674
26532675< div class ="stylebody ">
2654- < p class ="drake "> Unit tests may catch exceptions using
2655- < a href ="https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md#exception-assertions "> EXPECT_THROW</ a >
2656- or
2657- < a href ="https://github.com/RobotLocomotion/drake/blob/master/common/test_utilities/expect_throws_message.h "> DRAKE_EXPECT_THROWS_MESSAGE</ a > ,
2658- but only if the tested function's Doxygen documentation mentions that the
2659- function throws an exception.</ p >
2660-
26612676 < p class ="drake "> When documenting exceptions in an API, only state that
26622677 the function will throw < code > std::exception</ code > ; never promise a more
26632678 specific subclass:</ p >
@@ -2667,11 +2682,28 @@ <h3 id="Exceptions">Exceptions</h3>
26672682 to refactor the code in ways that keeps the subclass unchanged.</ li >
26682683 < li > There's no great way to deprecate a particular exception signature.</ li >
26692684 < li > Since we can't catch exceptions anyway, nevermind use a multi-layer-catch
2670- by specific subclasses, the only purpose of a subclass is for improved error
2671- reporting -- this purpose is still met by throwing a subclass, but we don't
2672- need to document it in Doxygen for this purpose.</ li >
2685+ by specific subclasses, the only purpose of choosing a specific subclass is
2686+ for improved error reporting -- this purpose is still met by throwing a
2687+ subclass, but we don't need to document it in the API for this purpose.</ li >
26732688 </ ul >
2674- </ p >
2689+
2690+ < p class ="drake "> When throwing and there is no particular reason to choose
2691+ any particular subclass of < code > std::exception</ code > to be thrown, prefer
2692+ to use < code > std::logic_error</ code > as our nominal concrete type. The
2693+ clarity of the error message string matters more than the subtype choice.</ p >
2694+
2695+ < p class ="drake "> Unit tests may catch exceptions using
2696+ < a href ="https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md#exception-assertions "> EXPECT_THROW</ a >
2697+ or
2698+ < a href ="https://github.com/RobotLocomotion/drake/blob/master/common/test_utilities/expect_throws_message.h "> DRAKE_EXPECT_THROWS_MESSAGE</ a > :</ p >
2699+ < ul class ="drake ">
2700+ < li > Only test for exceptions under the conditions where the tested function's
2701+ API documentation promises that the function throws an exception.</ li >
2702+ < li > Only test for a specific subtype of < code > std::exception</ code > when the
2703+ subtype is < em > necessary</ em > to determine whether the code behaved correctly,
2704+ e.g., in cases where the code may throw several different types of exception
2705+ and the subtype fully disambiguates which condition was triggered. (This is
2706+ rare.)</ li >
26752707</ div >
26762708
26772709< p class ="pros "> </ p >
@@ -4716,12 +4748,15 @@ <h3 id="General_Naming_Rules">General Naming Rules</h3>
47164748variable names</ a > .</ p >
47174749
47184750< p class ="exception drake ">
4719- Method names may violate both the name structure standard and the “long,
4720- human-readable” standard above if a short, non-compliant name more closely
4721- matches the common conventions of the field. For instance, the matrix
4722- portion of a linear complementarity constraint is traditionally ‘M’ (one
4723- letter, upper-case); it is not mandatory to downcase it or give it a more
4724- verbose name.
4751+ Variable and method names may violate both the capitalization standard and
4752+ the “long, human-readable” standard above if a short, non-compliant name
4753+ more closely matches the common conventions of the field. For instance, the
4754+ matrix portion of a linear complementarity constraint is traditionally ‘M’
4755+ (one letter, upper-case); it is not mandatory to downcase it or give it a
4756+ more verbose name. However, even if a variable name is capitalized to
4757+ match common conventions, we still use underscores ("snake case") to delimit
4758+ its words, not "camel case". For instance, < code > Ai_triplets</ code > would
4759+ be the code spelling of the phrase “Aᵢ triplets”.
47254760</ p >
47264761< p class ="exception drake ">
47274762 Note that the Drake multibody tree and related types have their own naming
@@ -4859,6 +4894,46 @@ <h3 id="Constant_Names">Constant Names</h3>
48594894convention is optional for variables of other storage classes, e.g., automatic
48604895variables, otherwise the usual variable naming rules apply.</ p >
48614896
4897+ < div class ="drake ">
4898+
4899+ < p > Never use < code > kMixedCase</ code > style for template arguments. In the
4900+ typical case, a template argument will refer to differing values within the
4901+ same program, so is not a program-wide constant.</ p >
4902+
4903+ < pre > // OK - num_stages names to a value that is not a program-wide constant.
4904+
4905+ template <typename T, int num_stages = 2>
4906+ class RadauIntegrator { ... };
4907+ </ pre >
4908+
4909+ < pre class ="badcode "> // BAD - kNumStages is not a program-wide constant.
4910+
4911+ template <typename T, int kNumStages = 2>
4912+ class RadauIntegrator { ... };
4913+ </ pre >
4914+
4915+ < p > Even in the case of class data members (whether static or non-static),
4916+ never add a trailing underscore to a < code > kMixedCase</ code > name.</ p >
4917+
4918+ < pre > class Foo {
4919+ ...
4920+ private:
4921+ const std::string default_name_{"name"}; // OK - snake_case_ member.
4922+ const std::string kDefaultName{"name"}; // OK - program-wide constant.
4923+ static const int kDefaultValue{1000}; // OK - static constant.
4924+ };
4925+ </ pre >
4926+
4927+ < pre class ="badcode "> class Foo {
4928+ ...
4929+ private:
4930+ const std::string kDefaultName_{"name"}; // Bad - underscore.
4931+ static const int kDefaultValue_{1000}; // Bad - underscore.
4932+ };
4933+ </ pre >
4934+
4935+ </ div >
4936+
48624937< h3 id ="Function_Names "> Function Names</ h3 >
48634938
48644939< p > Regular functions have mixed case; accessors and mutators may be named
0 commit comments