Karl Wiberg | bb821e2 | 2017-09-03 03:02:12 | [diff] [blame] | 1 | # WebRTC coding style guide |
| 2 | |
Karl Wiberg | e1d464e | 2017-09-08 13:12:36 | [diff] [blame] | 3 | ## **General advice** |
Karl Wiberg | 241d710 | 2017-09-08 13:07:15 | [diff] [blame] | 4 | |
| 5 | Some older parts of the code violate the style guide in various ways. |
| 6 | |
| 7 | * If making small changes to such code, follow the style guide when |
| 8 | it’s reasonable to do so, but in matters of formatting etc., it is |
| 9 | often better to be consistent with the surrounding code. |
| 10 | * If making large changes to such code, consider first cleaning it up |
| 11 | in a separate CL. |
| 12 | |
Karl Wiberg | e1d464e | 2017-09-08 13:12:36 | [diff] [blame] | 13 | ## **C++** |
Karl Wiberg | bb821e2 | 2017-09-03 03:02:12 | [diff] [blame] | 14 | |
| 15 | WebRTC follows the [Chromium][chr-style] and [Google][goog-style] C++ |
Karl Wiberg | e1ed241 | 2017-09-06 09:10:23 | [diff] [blame] | 16 | style guides. In cases where they conflict, the Chromium style guide |
| 17 | trumps the Google style guide, and the rules in this file trump them |
| 18 | both. |
Karl Wiberg | bb821e2 | 2017-09-03 03:02:12 | [diff] [blame] | 19 | |
Karl Wiberg | 91d0ab7 | 2017-09-07 15:05:31 | [diff] [blame] | 20 | [chr-style]: https://chromium.googlesource.com/chromium/src/+/HEAD/styleguide/c++/c++.md |
Karl Wiberg | bb821e2 | 2017-09-03 03:02:12 | [diff] [blame] | 21 | [goog-style]: https://google.github.io/styleguide/cppguide.html |
| 22 | |
Karl Wiberg | e1ed241 | 2017-09-06 09:10:23 | [diff] [blame] | 23 | ### ArrayView |
Karl Wiberg | bb821e2 | 2017-09-03 03:02:12 | [diff] [blame] | 24 | |
Karl Wiberg | e1ed241 | 2017-09-06 09:10:23 | [diff] [blame] | 25 | When passing an array of values to a function, use `rtc::ArrayView` |
| 26 | whenever possible—that is, whenever you’re not passing ownership of |
| 27 | the array, and don’t allow the callee to change the array size. |
| 28 | |
| 29 | For example, |
| 30 | |
| 31 | instead of | use |
| 32 | ------------------------------------|--------------------- |
| 33 | `const std::vector<T>&` | `ArrayView<const T>` |
| 34 | `const T* ptr, size_t num_elements` | `ArrayView<const T>` |
| 35 | `T* ptr, size_t num_elements` | `ArrayView<T>` |
| 36 | |
| 37 | See [the source](webrtc/api/array_view.h) for more detailed docs. |
Karl Wiberg | fb4e677 | 2017-09-04 09:27:33 | [diff] [blame] | 38 | |
Taylor Brandstetter | efc5fbd | 2017-12-08 19:42:15 | [diff] [blame] | 39 | ### sigslot |
| 40 | |
| 41 | sigslot is a lightweight library that adds a signal/slot language |
| 42 | construct to C++, making it easy to implement the observer pattern |
| 43 | with minimal boilerplate code. |
| 44 | |
| 45 | When adding a signal to a pure interface, **prefer to add a pure |
| 46 | virtual method that returns a reference to a signal**: |
| 47 | |
| 48 | ``` |
| 49 | sigslot::signal<int>& SignalFoo() = 0; |
| 50 | ``` |
| 51 | |
| 52 | As opposed to making it a public member variable, as a lot of legacy |
| 53 | code does: |
| 54 | |
| 55 | ``` |
| 56 | sigslot::signal<int> SignalFoo; |
| 57 | ``` |
| 58 | |
| 59 | The virtual method approach has the advantage that it keeps the |
| 60 | interface stateless, and gives the subclass more flexibility in how it |
| 61 | implements the signal. It may: |
| 62 | |
| 63 | * Have its own signal as a member variable. |
| 64 | * Use a `sigslot::repeater`, to repeat a signal of another object: |
| 65 | |
| 66 | ``` |
| 67 | sigslot::repeater<int> foo_; |
| 68 | /* ... */ |
| 69 | foo_.repeat(bar_.SignalFoo()); |
| 70 | ``` |
| 71 | * Just return another object's signal directly, if the other object's |
| 72 | lifetime is the same as its own. |
| 73 | |
| 74 | ``` |
| 75 | sigslot::signal<int>& SignalFoo() { return bar_.SignalFoo(); } |
| 76 | ``` |
| 77 | |
Karl Wiberg | e1d464e | 2017-09-08 13:12:36 | [diff] [blame] | 78 | ## **C** |
Karl Wiberg | fb4e677 | 2017-09-04 09:27:33 | [diff] [blame] | 79 | |
| 80 | There’s a substantial chunk of legacy C code in WebRTC, and a lot of |
| 81 | it is old enough that it violates the parts of the C++ style guide |
| 82 | that also applies to C (naming etc.) for the simple reason that it |
| 83 | pre-dates the use of the current C++ style guide for this code base. |
| 84 | |
| 85 | * If making small changes to C code, mimic the style of the |
| 86 | surrounding code. |
| 87 | * If making large changes to C code, consider converting the whole |
| 88 | thing to C++ first. |
Karl Wiberg | ee3d760 | 2017-09-04 12:46:47 | [diff] [blame] | 89 | |
Karl Wiberg | e1d464e | 2017-09-08 13:12:36 | [diff] [blame] | 90 | ## **Java** |
Karl Wiberg | 241d710 | 2017-09-08 13:07:15 | [diff] [blame] | 91 | |
| 92 | WebRTC follows the [Google Java style guide][goog-java-style]. |
| 93 | |
| 94 | [goog-java-style]: https://google.github.io/styleguide/javaguide.html |
| 95 | |
Karl Wiberg | e1d464e | 2017-09-08 13:12:36 | [diff] [blame] | 96 | ## **Objective-C and Objective-C++** |
Karl Wiberg | 241d710 | 2017-09-08 13:07:15 | [diff] [blame] | 97 | |
| 98 | WebRTC follows the |
| 99 | [Chromium Objective-C and Objective-C++ style guide][chr-objc-style]. |
| 100 | |
| 101 | [chr-objc-style]: https://chromium.googlesource.com/chromium/src/+/HEAD/styleguide/objective-c/objective-c.md |
| 102 | |
Karl Wiberg | e1d464e | 2017-09-08 13:12:36 | [diff] [blame] | 103 | ## **Python** |
Karl Wiberg | 241d710 | 2017-09-08 13:07:15 | [diff] [blame] | 104 | |
| 105 | WebRTC follows [Chromium’s Python style][chr-py-style]. |
| 106 | |
| 107 | [chr-py-style]: https://chromium.googlesource.com/chromium/src/+/HEAD/styleguide/styleguide.md#python |
| 108 | |
Karl Wiberg | e1d464e | 2017-09-08 13:12:36 | [diff] [blame] | 109 | ## **Build files** |
Karl Wiberg | ee3d760 | 2017-09-04 12:46:47 | [diff] [blame] | 110 | |
Karl Wiberg | 91d0ab7 | 2017-09-07 15:05:31 | [diff] [blame] | 111 | The WebRTC build files are written in [GN][gn], and we follow |
| 112 | the [Chromium GN style guide][chr-gn-style]. Additionally, there are |
| 113 | some WebRTC-specific rules below; in case of conflict, they trump the |
| 114 | Chromium style guide. |
| 115 | |
| 116 | [gn]: https://chromium.googlesource.com/chromium/src/tools/gn/ |
| 117 | [chr-gn-style]: https://chromium.googlesource.com/chromium/src/tools/gn/+/HEAD/docs/style_guide.md |
| 118 | |
Per Kjellander | a7f2d84 | 2018-01-10 15:54:53 | [diff] [blame^] | 119 | ### <a name="webrtc-gn-templates"></a>WebRTC-specific GN templates |
Karl Wiberg | 91d0ab7 | 2017-09-07 15:05:31 | [diff] [blame] | 120 | |
| 121 | Use the following [GN templates][gn-templ] to ensure that all |
| 122 | our [targets][gn-target] are built with the same configuration: |
| 123 | |
| 124 | instead of | use |
| 125 | -----------------|--------------------- |
| 126 | `executable` | `rtc_executable` |
| 127 | `shared_library` | `rtc_shared_library` |
| 128 | `source_set` | `rtc_source_set` |
| 129 | `static_library` | `rtc_static_library` |
| 130 | `test` | `rtc_test` |
| 131 | |
| 132 | [gn-templ]: https://chromium.googlesource.com/chromium/src/tools/gn/+/HEAD/docs/language.md#Templates |
| 133 | [gn-target]: https://chromium.googlesource.com/chromium/src/tools/gn/+/HEAD/docs/language.md#Targets |
| 134 | |
Per Kjellander | a7f2d84 | 2018-01-10 15:54:53 | [diff] [blame^] | 135 | ### Target visibility and the native API |
| 136 | |
| 137 | The [WebRTC-specific GN templates](#webrtc-gn-templates) declare build |
| 138 | targets whose default `visibility` allows all other targets in the |
| 139 | WebRTC tree (and no targets outside the tree) to depend on them. |
| 140 | |
| 141 | Prefer to restrict the visibility if possible: |
| 142 | |
| 143 | * If a target is used by only one or a tiny number of other targets, |
| 144 | prefer to list them explicitly: `visibility = [ ":foo", ":bar" ]` |
| 145 | * If a target is used only by targets in the same `BUILD.gn` file: |
| 146 | `visibility = [ ":*" ]`. |
| 147 | |
| 148 | Setting `visibility = [ "*" ]` means that targets outside the WebRTC |
| 149 | tree can depend on this target; use this only for build targets whose |
| 150 | headers are part of the [native API](native-api.md). |
| 151 | |
Karl Wiberg | ee3d760 | 2017-09-04 12:46:47 | [diff] [blame] | 152 | ### Conditional compilation with the C preprocessor |
| 153 | |
| 154 | Avoid using the C preprocessor to conditionally enable or disable |
Karl Wiberg | 91d0ab7 | 2017-09-07 15:05:31 | [diff] [blame] | 155 | pieces of code. But if you can’t avoid it, introduce a GN variable, |
Karl Wiberg | ee3d760 | 2017-09-04 12:46:47 | [diff] [blame] | 156 | and then set a preprocessor constant to either 0 or 1 in the build |
| 157 | targets that need it: |
| 158 | |
| 159 | ``` |
| 160 | if (apm_debug_dump) { |
| 161 | defines = [ "WEBRTC_APM_DEBUG_DUMP=1" ] |
| 162 | } else { |
| 163 | defines = [ "WEBRTC_APM_DEBUG_DUMP=0" ] |
| 164 | } |
| 165 | ``` |
| 166 | |
| 167 | In the C, C++, or Objective-C files, use `#if` when testing the flag, |
| 168 | not `#ifdef` or `#if defined()`: |
| 169 | |
| 170 | ``` |
| 171 | #if WEBRTC_APM_DEBUG_DUMP |
| 172 | // One way. |
| 173 | #else |
| 174 | // Or another. |
| 175 | #endif |
| 176 | ``` |
| 177 | |
| 178 | When combined with the `-Wundef` compiler option, this produces |
| 179 | compile time warnings if preprocessor symbols are misspelled, or used |
| 180 | without corresponding build rules to set them. |