@@ -2619,6 +2619,28 @@ <h3 id="Pass_By_Value">Pass by Value</h3>
2619
2619
< 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 >
2620
2620
</ ul >
2621
2621
</ 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
+
2622
2644
</ div >
2623
2645
2624
2646
< h3 id ="Friends "> Friends</ h3 >
@@ -2651,13 +2673,6 @@ <h3 id="Exceptions">Exceptions</h3>
2651
2673
noted below.</ p >
2652
2674
2653
2675
< 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
-
2661
2676
< p class ="drake "> When documenting exceptions in an API, only state that
2662
2677
the function will throw < code > std::exception</ code > ; never promise a more
2663
2678
specific subclass:</ p >
@@ -2667,11 +2682,28 @@ <h3 id="Exceptions">Exceptions</h3>
2667
2682
to refactor the code in ways that keeps the subclass unchanged.</ li >
2668
2683
< li > There's no great way to deprecate a particular exception signature.</ li >
2669
2684
< 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 >
2673
2688
</ 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 >
2675
2707
</ div >
2676
2708
2677
2709
< p class ="pros "> </ p >
@@ -4716,12 +4748,15 @@ <h3 id="General_Naming_Rules">General Naming Rules</h3>
4716
4748
variable names</ a > .</ p >
4717
4749
4718
4750
< 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”.
4725
4760
</ p >
4726
4761
< p class ="exception drake ">
4727
4762
Note that the Drake multibody tree and related types have their own naming
@@ -4859,6 +4894,46 @@ <h3 id="Constant_Names">Constant Names</h3>
4859
4894
convention is optional for variables of other storage classes, e.g., automatic
4860
4895
variables, otherwise the usual variable naming rules apply.</ p >
4861
4896
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
+
4862
4937
< h3 id ="Function_Names "> Function Names</ h3 >
4863
4938
4864
4939
< p > Regular functions have mixed case; accessors and mutators may be named
0 commit comments