blob: 80c33021562c634154563f6cc0d77bee0806af93 [file] [log] [blame] [view]
Karl Wibergbb821e22017-09-03 03:02:121# WebRTC coding style guide
2
Karl Wiberge1d464e2017-09-08 13:12:363## **General advice**
Karl Wiberg241d7102017-09-08 13:07:154
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 its 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 Wiberge1d464e2017-09-08 13:12:3613## **C++**
Karl Wibergbb821e22017-09-03 03:02:1214
15WebRTC follows the [Chromium][chr-style] and [Google][goog-style] C++
Karl Wiberge1ed2412017-09-06 09:10:2316style guides. In cases where they conflict, the Chromium style guide
17trumps the Google style guide, and the rules in this file trump them
18both.
Karl Wibergbb821e22017-09-03 03:02:1219
Karl Wiberg91d0ab72017-09-07 15:05:3120[chr-style]: https://chromium.googlesource.com/chromium/src/+/HEAD/styleguide/c++/c++.md
Karl Wibergbb821e22017-09-03 03:02:1221[goog-style]: https://google.github.io/styleguide/cppguide.html
22
Karl Wiberg180d9922018-03-15 10:21:0523### C++ version
24
Mirko Bonadei1b6a30d2019-09-11 07:02:2325WebRTC is written in C++14, but with some restrictions:
Karl Wiberg180d9922018-03-15 10:21:0526
Mirko Bonadei1b6a30d2019-09-11 07:02:2327* 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 Wiberg180d9922018-03-15 10:21:0531
Mirko Bonadei1b6a30d2019-09-11 07:02:2332[chromium-cpp]: https://chromium-cpp.appspot.com/
Karl Wiberg180d9922018-03-15 10:21:0533
Karl Wiberg87880882020-06-03 08:33:2534Unlike 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
Karl Wibergc3af97d2018-08-27 02:26:1838### 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
Karl Wiberg08c5cb02018-03-14 11:23:1245### <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 dont pull in definitions for everything they
64declare.
65
66[Examples and exceptions](style-guide/h-cc-pairs.md).
67
Danil Chapovalov375eff42019-12-11 11:45:0868### 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
Karl Wiberge1ed2412017-09-06 09:10:2378### ArrayView
Karl Wibergbb821e22017-09-03 03:02:1279
Karl Wiberge1ed2412017-09-06 09:10:2380When passing an array of values to a function, use `rtc::ArrayView`
81whenever possiblethat is, whenever youre not passing ownership of
82the array, and dont 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
Karl Wiberg3b4c5902018-03-14 11:27:5592See [the source](api/array_view.h) for more detailed docs.
Karl Wibergfb4e6772017-09-04 09:27:3393
Taylor Brandstetterefc5fbd2017-12-08 19:42:1594### 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
Karl Wiberg0d446252018-03-19 22:27:35133### std::bind
134
135Dont 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 its 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
Taylor Brandstetter212a2062017-10-12 18:22:48145### 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
Karl Wiberge1d464e2017-09-08 13:12:36153## **C**
Karl Wibergfb4e6772017-09-04 09:27:33154
155Theres 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.
Karl Wibergee3d7602017-09-04 12:46:47164
Karl Wiberge1d464e2017-09-08 13:12:36165## **Java**
Karl Wiberg241d7102017-09-08 13:07:15166
167WebRTC follows the [Google Java style guide][goog-java-style].
168
169[goog-java-style]: https://google.github.io/styleguide/javaguide.html
170
Karl Wiberge1d464e2017-09-08 13:12:36171## **Objective-C and Objective-C++**
Karl Wiberg241d7102017-09-08 13:07:15172
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
Karl Wiberge1d464e2017-09-08 13:12:36178## **Python**
Karl Wiberg241d7102017-09-08 13:07:15179
180WebRTC follows [Chromiums Python style][chr-py-style].
181
182[chr-py-style]: https://chromium.googlesource.com/chromium/src/+/HEAD/styleguide/styleguide.md#python
183
Karl Wiberge1d464e2017-09-08 13:12:36184## **Build files**
Karl Wibergee3d7602017-09-04 12:46:47185
Karl Wiberg91d0ab72017-09-07 15:05:31186The 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
Per Kjellandera7f2d842018-01-10 15:54:53194### <a name="webrtc-gn-templates"></a>WebRTC-specific GN templates
Karl Wiberg91d0ab72017-09-07 15:05:31195
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
Per Kjellandera7f2d842018-01-10 15:54:53210### 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
Karl Wibergee3d7602017-09-04 12:46:47227### Conditional compilation with the C preprocessor
228
229Avoid using the C preprocessor to conditionally enable or disable
Karl Wiberg91d0ab72017-09-07 15:05:31230pieces of code. But if you cant avoid it, introduce a GN variable,
Karl Wibergee3d7602017-09-04 12:46:47231and 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.