1# WebRTC coding style guide 2 3<?% config.freshness.owner = 'danilchap' %?> 4<?% config.freshness.reviewed = '2022-01-17' %?> 5 6## General advice 7 8Some older parts of the code violate the style guide in various ways. 9If making large changes to such code, consider first cleaning it up in a 10 separate CL. 11 12## C++ 13 14WebRTC follows the [Chromium C++ style guide][chr-style] and the 15[Google C++ style guide][goog-style]. In cases where they conflict, the Chromium 16style guide trumps the Google style guide, and the rules in this file trump them 17both. 18 19[chr-style]: https://chromium.googlesource.com/chromium/src/+/main/styleguide/c++/c++.md 20[goog-style]: https://google.github.io/styleguide/cppguide.html 21 22### C++ version 23 24WebRTC is written in C++17, but with some restrictions: 25 26* We only allow the subset of C++17 (language and library) that is not banned by 27 Chromium; see the [list of banned C++ features in Chromium][chr-style-cpp]. 28* We only allow the subset of C++17 that is also valid C++20; otherwise, users 29 would not be able to compile WebRTC in C++20 mode. 30 31[chr-style-cpp]: https://chromium.googlesource.com/chromium/src/+/main/styleguide/c++/c++-features.md 32 33### Abseil 34 35You may use a subset of the utilities provided by the [Abseil][abseil] library 36when writing WebRTC C++ code; see the 37[instructions on how to use Abseil in WebRTC](abseil-in-webrtc.md). 38 39[abseil]: https://abseil.io/about/ 40 41### <a name="h-cc-pairs"></a>`.h` and `.cc` files come in pairs 42 43`.h` and `.cc` files should come in pairs, with the same name (except for the 44file type suffix), in the same directory, in the same build target. 45 46* If a declaration in `path/to/foo.h` has a definition in some `.cc` file, it 47 should be in `path/to/foo.cc`. 48* If a definition in `path/to/foo.cc` file has a declaration in some `.h` file, 49 it should be in `path/to/foo.h`. 50* Omit the `.cc` file if it would have been empty, but still list the `.h` file 51 in a build target. 52* Omit the `.h` file if it would have been empty. (This can happen with unit 53 test `.cc` files, and with `.cc` files that define `main`.) 54 55See also the 56[examples and exceptions on how to treat `.h` and `.cpp` files](style-guide/h-cc-pairs.md). 57 58This makes the source code easier to navigate and organize, and precludes some 59questionable build system practices such as having build targets that don't pull 60in definitions for everything they declare. 61 62### `TODO` comments 63 64Follow the [Google styleguide for `TODO` comments][goog-style-todo]. When 65referencing a WebRTC bug, prefer using the URL form (excluding the scheme part): 66 67```cpp 68// TODO(bugs.webrtc.org/12345): Delete the hack when blocking bugs are resolved. 69``` 70 71The short form used in commit messages, e.g. `webrtc:12345`, is discouraged. 72 73[goog-style-todo]: https://google.github.io/styleguide/cppguide.html#TODO_Comments 74 75### Deprecation 76 77Annotate the declarations of deprecated functions and classes with the 78[`[[deprecated]]` attribute][DEPRECATED] to cause an error when they're used 79inside WebRTC and a compiler warning when they're used by dependant projects. 80Like so: 81 82```cpp 83[[deprecated("bugs.webrtc.org/12345")]] 84std::pony PonyPlz(const std::pony_spec& ps); 85``` 86 87NOTE 1: The annotation goes on the declaration in the `.h` file, not the 88definition in the `.cc` file! 89 90NOTE 2: In order to have unit tests that use the deprecated function without 91getting errors, do something like this: 92 93```cpp 94std::pony DEPRECATED_PonyPlz(const std::pony_spec& ps); 95[[deprecated("bugs.webrtc.org/12345")]] 96inline std::pony PonyPlz(const std::pony_spec& ps) { 97 return DEPRECATED_PonyPlz(ps); 98} 99``` 100 101In other words, rename the existing function, and provide an inline wrapper 102using the original name that calls it. That way, callers who are willing to 103call it using the `DEPRECATED_`-prefixed name don't get the warning. 104 105NOTE 3: Occasionally, with long descriptions, `git cl format` will do the wrong 106thing with the attribute. In that case, you can use the 107[`ABSL_DEPRECATED` macro][ABSL_DEPRECATED], which is formatted in a more 108readable way. 109 110[DEPRECATED]: https://en.cppreference.com/w/cpp/language/attributes/deprecated 111[ABSL_DEPRECATED]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/abseil-cpp/absl/base/attributes.h?q=ABSL_DEPRECATED 112 113### ArrayView 114 115When passing an array of values to a function, use `rtc::ArrayView` 116whenever possible—that is, whenever you're not passing ownership of 117the array, and don't allow the callee to change the array size. 118 119For example, 120 121| instead of | use | 122|-------------------------------------|----------------------| 123| `const std::vector<T>&` | `ArrayView<const T>` | 124| `const T* ptr, size_t num_elements` | `ArrayView<const T>` | 125| `T* ptr, size_t num_elements` | `ArrayView<T>` | 126 127See the [source code for `rtc::ArrayView`](api/array_view.h) for more detailed 128docs. 129 130### sigslot 131 132SIGSLOT IS DEPRECATED. 133 134Prefer `webrtc::CallbackList`, and manage thread safety yourself. 135 136### Smart pointers 137 138The following smart pointer types are recommended: 139 140 * `std::unique_ptr` for all singly-owned objects 141 * `rtc::scoped_refptr` for all objects with shared ownership 142 143Use of `std::shared_ptr` is *not permitted*. It is banned in the Chromium style 144guide (overriding the Google style guide). See the 145[list of banned C++ library features in Chromium][chr-std-shared-ptr] for more 146information. 147 148In most cases, one will want to explicitly control lifetimes, and therefore use 149`std::unique_ptr`, but in some cases, for instance where references have to 150exist both from the API users and internally, with no way to invalidate pointers 151held by the API user, `rtc::scoped_refptr` can be appropriate. 152 153[chr-std-shared-ptr]: https://chromium.googlesource.com/chromium/src/+/main/styleguide/c++/c++-features.md#shared-pointers-banned 154 155### `std::bind` 156 157Don't use `std::bind`—there are pitfalls, and lambdas are almost as succinct and 158already familiar to modern C++ programmers. 159 160### `std::function` 161 162`std::function` is allowed, but remember that it's not the right tool for every 163occasion. Prefer to use interfaces when that makes sense, and consider 164`rtc::FunctionView` for cases where the callee will not save the function 165object. 166 167### Forward declarations 168 169WebRTC follows the 170[Google C++ style guide on forward declarations][goog-forward-declarations]. 171In summary: avoid using forward declarations where possible; just `#include` the 172headers you need. 173 174[goog-forward-declarations]: https://google.github.io/styleguide/cppguide.html#Forward_Declarations 175 176### RTTI and dynamic_cast 177 178The Google style guide [permits the use of dynamic_cast](https://google.github.io/styleguide/cppguide.html#Run-Time_Type_Information__RTTI_). 179 180However, WebRTC does not permit it. WebRTC (and Chrome) is compiled with the 181-fno-rtti flag, and the overhead of enabling RTTI it is on the order of 220 182Kbytes (for Android Arm64). 183 184Use static_cast and take your own steps to ensure type safety. 185 186## C 187 188There's a substantial chunk of legacy C code in WebRTC, and a lot of it is old 189enough that it violates the parts of the C++ style guide that also applies to C 190(naming etc.) for the simple reason that it pre-dates the use of the current C++ 191style guide for this code base. If making large changes to C code, consider 192converting the whole thing to C++ first. 193 194## Java 195 196WebRTC follows the [Google Java style guide][goog-java-style]. 197 198[goog-java-style]: https://google.github.io/styleguide/javaguide.html 199 200## Objective-C and Objective-C++ 201 202WebRTC follows the 203[Chromium Objective-C and Objective-C++ style guide][chr-objc-style]. 204 205[chr-objc-style]: https://chromium.googlesource.com/chromium/src/+/main/styleguide/objective-c/objective-c.md 206 207## Python 208 209WebRTC follows [Chromium's Python style][chr-py-style]. 210 211[chr-py-style]: https://chromium.googlesource.com/chromium/src/+/main/styleguide/python/python.md 212 213## Build files 214 215The WebRTC build files are written in [GN][gn], and we follow the 216[GN style guide][gn-style]. Additionally, there are some 217WebRTC-specific rules below; in case of conflict, they trump the Chromium style 218guide. 219 220[gn]: https://gn.googlesource.com/gn/ 221[gn-style]: https://gn.googlesource.com/gn/+/HEAD/docs/style_guide.md 222 223### <a name="webrtc-gn-templates"></a>WebRTC-specific GN templates 224 225Use the following [GN templates][gn-templ] to ensure that all our 226[GN targets][gn-target] are built with the same configuration: 227 228| instead of | use | 229|------------------|----------------------| 230| `executable` | `rtc_executable` | 231| `shared_library` | `rtc_shared_library` | 232| `source_set` | `rtc_source_set` | 233| `static_library` | `rtc_static_library` | 234| `test` | `rtc_test` | 235 236 237[gn-templ]: https://gn.googlesource.com/gn/+/HEAD/docs/language.md#Templates 238[gn-target]: https://gn.googlesource.com/gn/+/HEAD/docs/language.md#Targets 239 240### Target visibility and the native API 241 242The [WebRTC-specific GN templates](#webrtc-gn-templates) declare build targets 243whose default `visibility` allows all other targets in the WebRTC tree (and no 244targets outside the tree) to depend on them. 245 246Prefer to restrict the `visibility` if possible: 247 248* If a target is used by only one or a tiny number of other targets, prefer to 249 list them explicitly: `visibility = [ ":foo", ":bar" ]` 250* If a target is used only by targets in the same `BUILD.gn` file: 251 `visibility = [ ":*" ]`. 252 253Setting `visibility = [ "*" ]` means that targets outside the WebRTC tree can 254depend on this target; use this only for build targets whose headers are part of 255the [native WebRTC API](native-api.md). 256 257### Conditional compilation with the C preprocessor 258 259Avoid using the C preprocessor to conditionally enable or disable pieces of 260code. But if you can't avoid it, introduce a GN variable, and then set a 261preprocessor constant to either 0 or 1 in the build targets that need it: 262 263```gn 264if (apm_debug_dump) { 265 defines = [ "WEBRTC_APM_DEBUG_DUMP=1" ] 266} else { 267 defines = [ "WEBRTC_APM_DEBUG_DUMP=0" ] 268} 269``` 270 271In the C, C++, or Objective-C files, use `#if` when testing the flag, 272not `#ifdef` or `#if defined()`: 273 274```c 275#if WEBRTC_APM_DEBUG_DUMP 276// One way. 277#else 278// Or another. 279#endif 280``` 281 282When combined with the `-Wundef` compiler option, this produces compile time 283warnings if preprocessor symbols are misspelled, or used without corresponding 284build rules to set them. 285