xref: /aosp_15_r20/external/webrtc/g3doc/style-guide.md (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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