• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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