1# WebRTC coding style guide 2 3## **General advice** 4 5Some 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 13## **C++** 14 15WebRTC follows the [Chromium][chr-style] and [Google][goog-style] C++ 16style guides. In cases where they conflict, the Chromium style guide 17trumps the Google style guide, and the rules in this file trump them 18both. 19 20[chr-style]: https://chromium.googlesource.com/chromium/src/+/HEAD/styleguide/c++/c++.md 21[goog-style]: https://google.github.io/styleguide/cppguide.html 22 23### C++ version 24 25WebRTC is written in C++14, but with some restrictions: 26 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. 31 32[chromium-cpp]: https://chromium-cpp.appspot.com/ 33 34Unlike the Chromium and Google C++ style guides, we do not allow C++20-style 35designated initializers, because we want to stay compatible with compilers that 36do not yet support them. 37 38### Abseil 39 40You may use a subset of the utilities provided by the [Abseil][abseil] 41library when writing WebRTC C++ code. [Details](abseil-in-webrtc.md). 42 43[abseil]: https://abseil.io/about/ 44 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 48for the file type suffix), in the same directory, in the same build 49target. 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 61This makes the source code easier to navigate and organize, and 62precludes some questionable build system practices such as having 63build targets that don’t pull in definitions for everything they 64declare. 65 66[Examples and exceptions](style-guide/h-cc-pairs.md). 67 68### TODO comments 69 70Follow the [Google style][goog-style-todo]. When referencing a WebRTC bug, 71prefer 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 78### ArrayView 79 80When passing an array of values to a function, use `rtc::ArrayView` 81whenever possible—that is, whenever you’re not passing ownership of 82the array, and don’t allow the callee to change the array size. 83 84For example, 85 86instead 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 92See [the source](api/array_view.h) for more detailed docs. 93 94### sigslot 95 96sigslot is a lightweight library that adds a signal/slot language 97construct to C++, making it easy to implement the observer pattern 98with minimal boilerplate code. 99 100When adding a signal to a pure interface, **prefer to add a pure 101virtual method that returns a reference to a signal**: 102 103``` 104sigslot::signal<int>& SignalFoo() = 0; 105``` 106 107As opposed to making it a public member variable, as a lot of legacy 108code does: 109 110``` 111sigslot::signal<int> SignalFoo; 112``` 113 114The virtual method approach has the advantage that it keeps the 115interface stateless, and gives the subclass more flexibility in how it 116implements 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 133### std::bind 134 135Don’t use `std::bind`—there are pitfalls, and lambdas are almost as 136succinct 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 141for every occasion. Prefer to use interfaces when that makes sense, 142and consider `rtc::FunctionView` for cases where the callee will not 143save the function object. 144 145### Forward declarations 146 147WebRTC follows the [Google][goog-forward-declarations] C++ style guide 148with respect to forward declarations. In summary: avoid using forward 149declarations where possible; just `#include` the headers you need. 150 151[goog-forward-declarations]: https://google.github.io/styleguide/cppguide.html#Forward_Declarations 152 153## **C** 154 155There’s a substantial chunk of legacy C code in WebRTC, and a lot of 156it is old enough that it violates the parts of the C++ style guide 157that also applies to C (naming etc.) for the simple reason that it 158pre-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. 164 165## **Java** 166 167WebRTC follows the [Google Java style guide][goog-java-style]. 168 169[goog-java-style]: https://google.github.io/styleguide/javaguide.html 170 171## **Objective-C and Objective-C++** 172 173WebRTC 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 178## **Python** 179 180WebRTC 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 184## **Build files** 185 186The WebRTC build files are written in [GN][gn], and we follow 187the [Chromium GN style guide][chr-gn-style]. Additionally, there are 188some WebRTC-specific rules below; in case of conflict, they trump the 189Chromium 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 194### <a name="webrtc-gn-templates"></a>WebRTC-specific GN templates 195 196Use the following [GN templates][gn-templ] to ensure that all 197our [targets][gn-target] are built with the same configuration: 198 199instead 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 210### Target visibility and the native API 211 212The [WebRTC-specific GN templates](#webrtc-gn-templates) declare build 213targets whose default `visibility` allows all other targets in the 214WebRTC tree (and no targets outside the tree) to depend on them. 215 216Prefer 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 223Setting `visibility = [ "*" ]` means that targets outside the WebRTC 224tree can depend on this target; use this only for build targets whose 225headers are part of the [native API](native-api.md). 226 227### Conditional compilation with the C preprocessor 228 229Avoid using the C preprocessor to conditionally enable or disable 230pieces of code. But if you can’t avoid it, introduce a GN variable, 231and then set a preprocessor constant to either 0 or 1 in the build 232targets that need it: 233 234``` 235if (apm_debug_dump) { 236 defines = [ "WEBRTC_APM_DEBUG_DUMP=1" ] 237} else { 238 defines = [ "WEBRTC_APM_DEBUG_DUMP=0" ] 239} 240``` 241 242In the C, C++, or Objective-C files, use `#if` when testing the flag, 243not `#ifdef` or `#if defined()`: 244 245``` 246#if WEBRTC_APM_DEBUG_DUMP 247// One way. 248#else 249// Or another. 250#endif 251``` 252 253When combined with the `-Wundef` compiler option, this produces 254compile time warnings if preprocessor symbols are misspelled, or used 255without corresponding build rules to set them. 256