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 | 180d992 | 2018-03-15 10:21:05 | [diff] [blame] | 23 | ### C++ version |
| 24 | |
Mirko Bonadei | 1b6a30d | 2019-09-11 07:02:23 | [diff] [blame] | 25 | WebRTC is written in C++14, but with some restrictions: |
Karl Wiberg | 180d992 | 2018-03-15 10:21:05 | [diff] [blame] | 26 | |
Mirko Bonadei | 1b6a30d | 2019-09-11 07:02:23 | [diff] [blame] | 27 | * We only allow the subset of C++14 (language and library) that is not |
| 28 | banned by Chromium; see [this page][chromium-cpp]. |
| 29 | * We only allow the subset of C++14 that is also valid C++17; |
| 30 | otherwise, users would not be able to compile WebRTC in C++17 mode. |
Karl Wiberg | 180d992 | 2018-03-15 10:21:05 | [diff] [blame] | 31 | |
Mirko Bonadei | 1b6a30d | 2019-09-11 07:02:23 | [diff] [blame] | 32 | [chromium-cpp]: https://chromium-cpp.appspot.com/ |
Karl Wiberg | 180d992 | 2018-03-15 10:21:05 | [diff] [blame] | 33 | |
Karl Wiberg | 8788088 | 2020-06-03 08:33:25 | [diff] [blame] | 34 | Unlike the Chromium and Google C++ style guides, we do not allow C++20-style |
| 35 | designated initializers, because we want to stay compatible with compilers that |
| 36 | do not yet support them. |
| 37 | |
Karl Wiberg | c3af97d | 2018-08-27 02:26:18 | [diff] [blame] | 38 | ### Abseil |
| 39 | |
| 40 | You may use a subset of the utilities provided by the [Abseil][abseil] |
| 41 | library when writing WebRTC C++ code. [Details](abseil-in-webrtc.md). |
| 42 | |
| 43 | [abseil]: https://abseil.io/about/ |
| 44 | |
Karl Wiberg | 08c5cb0 | 2018-03-14 11:23:12 | [diff] [blame] | 45 | ### <a name="h-cc-pairs"></a>`.h` and `.cc` files come in pairs |
| 46 | |
| 47 | `.h` and `.cc` files should come in pairs, with the same name (except |
| 48 | for the file type suffix), in the same directory, in the same build |
| 49 | target. |
| 50 | |
| 51 | * If a declaration in `path/to/foo.h` has a definition in some `.cc` |
| 52 | file, it should be in `path/to/foo.cc`. |
| 53 | * If a definition in `path/to/foo.cc` file has a declaration in some |
| 54 | `.h` file, it should be in `path/to/foo.h`. |
| 55 | * Omit the `.cc` file if it would have been empty, but still list the |
| 56 | `.h` file in a build target. |
| 57 | * Omit the `.h` file if it would have been empty. (This can happen |
| 58 | with unit test `.cc` files, and with `.cc` files that define |
| 59 | `main`.) |
| 60 | |
| 61 | This makes the source code easier to navigate and organize, and |
| 62 | precludes some questionable build system practices such as having |
| 63 | build targets that don’t pull in definitions for everything they |
| 64 | declare. |
| 65 | |
| 66 | [Examples and exceptions](style-guide/h-cc-pairs.md). |
| 67 | |
Danil Chapovalov | 375eff4 | 2019-12-11 11:45:08 | [diff] [blame] | 68 | ### TODO comments |
| 69 | |
| 70 | Follow the [Google style][goog-style-todo]. When referencing a WebRTC bug, |
| 71 | prefer the url form, e.g. |
| 72 | ``` |
| 73 | // TODO(bugs.webrtc.org/12345): Delete the hack when blocking bugs are resolved. |
| 74 | ``` |
| 75 | |
| 76 | [goog-style-todo]: https://google.github.io/styleguide/cppguide.html#TODO_Comments |
| 77 | |
Karl Wiberg | e1ed241 | 2017-09-06 09:10:23 | [diff] [blame] | 78 | ### ArrayView |
Karl Wiberg | bb821e2 | 2017-09-03 03:02:12 | [diff] [blame] | 79 | |
Karl Wiberg | e1ed241 | 2017-09-06 09:10:23 | [diff] [blame] | 80 | When passing an array of values to a function, use `rtc::ArrayView` |
| 81 | whenever possible—that is, whenever you’re not passing ownership of |
| 82 | the array, and don’t allow the callee to change the array size. |
| 83 | |
| 84 | For example, |
| 85 | |
| 86 | instead of | use |
| 87 | ------------------------------------|--------------------- |
| 88 | `const std::vector<T>&` | `ArrayView<const T>` |
| 89 | `const T* ptr, size_t num_elements` | `ArrayView<const T>` |
| 90 | `T* ptr, size_t num_elements` | `ArrayView<T>` |
| 91 | |
Karl Wiberg | 3b4c590 | 2018-03-14 11:27:55 | [diff] [blame] | 92 | See [the source](api/array_view.h) for more detailed docs. |
Karl Wiberg | fb4e677 | 2017-09-04 09:27:33 | [diff] [blame] | 93 | |
Taylor Brandstetter | efc5fbd | 2017-12-08 19:42:15 | [diff] [blame] | 94 | ### sigslot |
| 95 | |
| 96 | sigslot is a lightweight library that adds a signal/slot language |
| 97 | construct to C++, making it easy to implement the observer pattern |
| 98 | with minimal boilerplate code. |
| 99 | |
| 100 | When adding a signal to a pure interface, **prefer to add a pure |
| 101 | virtual method that returns a reference to a signal**: |
| 102 | |
| 103 | ``` |
| 104 | sigslot::signal<int>& SignalFoo() = 0; |
| 105 | ``` |
| 106 | |
| 107 | As opposed to making it a public member variable, as a lot of legacy |
| 108 | code does: |
| 109 | |
| 110 | ``` |
| 111 | sigslot::signal<int> SignalFoo; |
| 112 | ``` |
| 113 | |
| 114 | The virtual method approach has the advantage that it keeps the |
| 115 | interface stateless, and gives the subclass more flexibility in how it |
| 116 | implements the signal. It may: |
| 117 | |
| 118 | * Have its own signal as a member variable. |
| 119 | * Use a `sigslot::repeater`, to repeat a signal of another object: |
| 120 | |
| 121 | ``` |
| 122 | sigslot::repeater<int> foo_; |
| 123 | /* ... */ |
| 124 | foo_.repeat(bar_.SignalFoo()); |
| 125 | ``` |
| 126 | * Just return another object's signal directly, if the other object's |
| 127 | lifetime is the same as its own. |
| 128 | |
| 129 | ``` |
| 130 | sigslot::signal<int>& SignalFoo() { return bar_.SignalFoo(); } |
| 131 | ``` |
| 132 | |
Karl Wiberg | 0d44625 | 2018-03-19 22:27:35 | [diff] [blame] | 133 | ### std::bind |
| 134 | |
| 135 | Don’t use `std::bind`—there are pitfalls, and lambdas are almost as |
| 136 | succinct and already familiar to modern C++ programmers. |
| 137 | |
| 138 | ### std::function |
| 139 | |
| 140 | `std::function` is allowed, but remember that it’s not the right tool |
| 141 | for every occasion. Prefer to use interfaces when that makes sense, |
| 142 | and consider `rtc::FunctionView` for cases where the callee will not |
| 143 | save the function object. |
| 144 | |
Taylor Brandstetter | 212a206 | 2017-10-12 18:22:48 | [diff] [blame] | 145 | ### Forward declarations |
| 146 | |
| 147 | WebRTC follows the [Google][goog-forward-declarations] C++ style guide |
| 148 | with respect to forward declarations. In summary: avoid using forward |
| 149 | declarations where possible; just `#include` the headers you need. |
| 150 | |
| 151 | [goog-forward-declarations]: https://google.github.io/styleguide/cppguide.html#Forward_Declarations |
| 152 | |
Karl Wiberg | e1d464e | 2017-09-08 13:12:36 | [diff] [blame] | 153 | ## **C** |
Karl Wiberg | fb4e677 | 2017-09-04 09:27:33 | [diff] [blame] | 154 | |
| 155 | There’s a substantial chunk of legacy C code in WebRTC, and a lot of |
| 156 | it is old enough that it violates the parts of the C++ style guide |
| 157 | that also applies to C (naming etc.) for the simple reason that it |
| 158 | pre-dates the use of the current C++ style guide for this code base. |
| 159 | |
| 160 | * If making small changes to C code, mimic the style of the |
| 161 | surrounding code. |
| 162 | * If making large changes to C code, consider converting the whole |
| 163 | thing to C++ first. |
Karl Wiberg | ee3d760 | 2017-09-04 12:46:47 | [diff] [blame] | 164 | |
Karl Wiberg | e1d464e | 2017-09-08 13:12:36 | [diff] [blame] | 165 | ## **Java** |
Karl Wiberg | 241d710 | 2017-09-08 13:07:15 | [diff] [blame] | 166 | |
| 167 | WebRTC follows the [Google Java style guide][goog-java-style]. |
| 168 | |
| 169 | [goog-java-style]: https://google.github.io/styleguide/javaguide.html |
| 170 | |
Karl Wiberg | e1d464e | 2017-09-08 13:12:36 | [diff] [blame] | 171 | ## **Objective-C and Objective-C++** |
Karl Wiberg | 241d710 | 2017-09-08 13:07:15 | [diff] [blame] | 172 | |
| 173 | WebRTC follows the |
| 174 | [Chromium Objective-C and Objective-C++ style guide][chr-objc-style]. |
| 175 | |
| 176 | [chr-objc-style]: https://chromium.googlesource.com/chromium/src/+/HEAD/styleguide/objective-c/objective-c.md |
| 177 | |
Karl Wiberg | e1d464e | 2017-09-08 13:12:36 | [diff] [blame] | 178 | ## **Python** |
Karl Wiberg | 241d710 | 2017-09-08 13:07:15 | [diff] [blame] | 179 | |
| 180 | WebRTC follows [Chromium’s Python style][chr-py-style]. |
| 181 | |
| 182 | [chr-py-style]: https://chromium.googlesource.com/chromium/src/+/HEAD/styleguide/styleguide.md#python |
| 183 | |
Karl Wiberg | e1d464e | 2017-09-08 13:12:36 | [diff] [blame] | 184 | ## **Build files** |
Karl Wiberg | ee3d760 | 2017-09-04 12:46:47 | [diff] [blame] | 185 | |
Karl Wiberg | 91d0ab7 | 2017-09-07 15:05:31 | [diff] [blame] | 186 | The WebRTC build files are written in [GN][gn], and we follow |
| 187 | the [Chromium GN style guide][chr-gn-style]. Additionally, there are |
| 188 | some WebRTC-specific rules below; in case of conflict, they trump the |
| 189 | Chromium style guide. |
| 190 | |
| 191 | [gn]: https://chromium.googlesource.com/chromium/src/tools/gn/ |
| 192 | [chr-gn-style]: https://chromium.googlesource.com/chromium/src/tools/gn/+/HEAD/docs/style_guide.md |
| 193 | |
Per Kjellander | a7f2d84 | 2018-01-10 15:54:53 | [diff] [blame] | 194 | ### <a name="webrtc-gn-templates"></a>WebRTC-specific GN templates |
Karl Wiberg | 91d0ab7 | 2017-09-07 15:05:31 | [diff] [blame] | 195 | |
| 196 | Use the following [GN templates][gn-templ] to ensure that all |
| 197 | our [targets][gn-target] are built with the same configuration: |
| 198 | |
| 199 | instead of | use |
| 200 | -----------------|--------------------- |
| 201 | `executable` | `rtc_executable` |
| 202 | `shared_library` | `rtc_shared_library` |
| 203 | `source_set` | `rtc_source_set` |
| 204 | `static_library` | `rtc_static_library` |
| 205 | `test` | `rtc_test` |
| 206 | |
| 207 | [gn-templ]: https://chromium.googlesource.com/chromium/src/tools/gn/+/HEAD/docs/language.md#Templates |
| 208 | [gn-target]: https://chromium.googlesource.com/chromium/src/tools/gn/+/HEAD/docs/language.md#Targets |
| 209 | |
Per Kjellander | a7f2d84 | 2018-01-10 15:54:53 | [diff] [blame] | 210 | ### Target visibility and the native API |
| 211 | |
| 212 | The [WebRTC-specific GN templates](#webrtc-gn-templates) declare build |
| 213 | targets whose default `visibility` allows all other targets in the |
| 214 | WebRTC tree (and no targets outside the tree) to depend on them. |
| 215 | |
| 216 | Prefer to restrict the visibility if possible: |
| 217 | |
| 218 | * If a target is used by only one or a tiny number of other targets, |
| 219 | prefer to list them explicitly: `visibility = [ ":foo", ":bar" ]` |
| 220 | * If a target is used only by targets in the same `BUILD.gn` file: |
| 221 | `visibility = [ ":*" ]`. |
| 222 | |
| 223 | Setting `visibility = [ "*" ]` means that targets outside the WebRTC |
| 224 | tree can depend on this target; use this only for build targets whose |
| 225 | headers are part of the [native API](native-api.md). |
| 226 | |
Karl Wiberg | ee3d760 | 2017-09-04 12:46:47 | [diff] [blame] | 227 | ### Conditional compilation with the C preprocessor |
| 228 | |
| 229 | Avoid using the C preprocessor to conditionally enable or disable |
Karl Wiberg | 91d0ab7 | 2017-09-07 15:05:31 | [diff] [blame] | 230 | 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] | 231 | and then set a preprocessor constant to either 0 or 1 in the build |
| 232 | targets that need it: |
| 233 | |
| 234 | ``` |
| 235 | if (apm_debug_dump) { |
| 236 | defines = [ "WEBRTC_APM_DEBUG_DUMP=1" ] |
| 237 | } else { |
| 238 | defines = [ "WEBRTC_APM_DEBUG_DUMP=0" ] |
| 239 | } |
| 240 | ``` |
| 241 | |
| 242 | In the C, C++, or Objective-C files, use `#if` when testing the flag, |
| 243 | not `#ifdef` or `#if defined()`: |
| 244 | |
| 245 | ``` |
| 246 | #if WEBRTC_APM_DEBUG_DUMP |
| 247 | // One way. |
| 248 | #else |
| 249 | // Or another. |
| 250 | #endif |
| 251 | ``` |
| 252 | |
| 253 | When combined with the `-Wundef` compiler option, this produces |
| 254 | compile time warnings if preprocessor symbols are misspelled, or used |
| 255 | without corresponding build rules to set them. |