blob: 2a35fdc5d1a476ed75692e2101481e367683e7ab [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
25WebRTC is written in C++11, but with some restrictions:
26
27* We only allow the subset of C++11 (language and library) in the
28 allowed section of [this Chromium page][chromium-cpp11].
29* We only allow the subset of C++11 that is also valid C++14;
30 otherwise, users would not be able to compile WebRTC in C++14 mode.
31
32[chromium-cpp11]: https://chromium-cpp.appspot.com/
33
Karl Wibergc3af97d2018-08-27 02:26:1834### Abseil
35
36You may use a subset of the utilities provided by the [Abseil][abseil]
37library when writing WebRTC C++ code. [Details](abseil-in-webrtc.md).
38
39[abseil]: https://abseil.io/about/
40
Karl Wiberg08c5cb02018-03-14 11:23:1241### <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
44for the file type suffix), in the same directory, in the same build
45target.
46
47* If a declaration in `path/to/foo.h` has a definition in some `.cc`
48 file, it should be in `path/to/foo.cc`.
49* If a definition in `path/to/foo.cc` file has a declaration in some
50 `.h` file, it should be in `path/to/foo.h`.
51* Omit the `.cc` file if it would have been empty, but still list the
52 `.h` file in a build target.
53* Omit the `.h` file if it would have been empty. (This can happen
54 with unit test `.cc` files, and with `.cc` files that define
55 `main`.)
56
57This makes the source code easier to navigate and organize, and
58precludes some questionable build system practices such as having
59build targets that dont pull in definitions for everything they
60declare.
61
62[Examples and exceptions](style-guide/h-cc-pairs.md).
63
Karl Wiberge1ed2412017-09-06 09:10:2364### ArrayView
Karl Wibergbb821e22017-09-03 03:02:1265
Karl Wiberge1ed2412017-09-06 09:10:2366When passing an array of values to a function, use `rtc::ArrayView`
67whenever possiblethat is, whenever youre not passing ownership of
68the array, and dont allow the callee to change the array size.
69
70For example,
71
72instead of | use
73------------------------------------|---------------------
74`const std::vector<T>&` | `ArrayView<const T>`
75`const T* ptr, size_t num_elements` | `ArrayView<const T>`
76`T* ptr, size_t num_elements` | `ArrayView<T>`
77
Karl Wiberg3b4c5902018-03-14 11:27:5578See [the source](api/array_view.h) for more detailed docs.
Karl Wibergfb4e6772017-09-04 09:27:3379
Taylor Brandstetterefc5fbd2017-12-08 19:42:1580### sigslot
81
82sigslot is a lightweight library that adds a signal/slot language
83construct to C++, making it easy to implement the observer pattern
84with minimal boilerplate code.
85
86When adding a signal to a pure interface, **prefer to add a pure
87virtual method that returns a reference to a signal**:
88
89```
90sigslot::signal<int>& SignalFoo() = 0;
91```
92
93As opposed to making it a public member variable, as a lot of legacy
94code does:
95
96```
97sigslot::signal<int> SignalFoo;
98```
99
100The virtual method approach has the advantage that it keeps the
101interface stateless, and gives the subclass more flexibility in how it
102implements the signal. It may:
103
104* Have its own signal as a member variable.
105* Use a `sigslot::repeater`, to repeat a signal of another object:
106
107 ```
108 sigslot::repeater<int> foo_;
109 /* ... */
110 foo_.repeat(bar_.SignalFoo());
111 ```
112* Just return another object's signal directly, if the other object's
113 lifetime is the same as its own.
114
115 ```
116 sigslot::signal<int>& SignalFoo() { return bar_.SignalFoo(); }
117 ```
118
Karl Wiberg0d446252018-03-19 22:27:35119### std::bind
120
121Dont use `std::bind`there are pitfalls, and lambdas are almost as
122succinct and already familiar to modern C++ programmers.
123
124### std::function
125
126`std::function` is allowed, but remember that its not the right tool
127for every occasion. Prefer to use interfaces when that makes sense,
128and consider `rtc::FunctionView` for cases where the callee will not
129save the function object.
130
Taylor Brandstetter212a2062017-10-12 18:22:48131### Forward declarations
132
133WebRTC follows the [Google][goog-forward-declarations] C++ style guide
134with respect to forward declarations. In summary: avoid using forward
135declarations where possible; just `#include` the headers you need.
136
137[goog-forward-declarations]: https://google.github.io/styleguide/cppguide.html#Forward_Declarations
138
Karl Wiberge1d464e2017-09-08 13:12:36139## **C**
Karl Wibergfb4e6772017-09-04 09:27:33140
141Theres a substantial chunk of legacy C code in WebRTC, and a lot of
142it is old enough that it violates the parts of the C++ style guide
143that also applies to C (naming etc.) for the simple reason that it
144pre-dates the use of the current C++ style guide for this code base.
145
146* If making small changes to C code, mimic the style of the
147 surrounding code.
148* If making large changes to C code, consider converting the whole
149 thing to C++ first.
Karl Wibergee3d7602017-09-04 12:46:47150
Karl Wiberge1d464e2017-09-08 13:12:36151## **Java**
Karl Wiberg241d7102017-09-08 13:07:15152
153WebRTC follows the [Google Java style guide][goog-java-style].
154
155[goog-java-style]: https://google.github.io/styleguide/javaguide.html
156
Karl Wiberge1d464e2017-09-08 13:12:36157## **Objective-C and Objective-C++**
Karl Wiberg241d7102017-09-08 13:07:15158
159WebRTC follows the
160[Chromium Objective-C and Objective-C++ style guide][chr-objc-style].
161
162[chr-objc-style]: https://chromium.googlesource.com/chromium/src/+/HEAD/styleguide/objective-c/objective-c.md
163
Karl Wiberge1d464e2017-09-08 13:12:36164## **Python**
Karl Wiberg241d7102017-09-08 13:07:15165
166WebRTC follows [Chromiums Python style][chr-py-style].
167
168[chr-py-style]: https://chromium.googlesource.com/chromium/src/+/HEAD/styleguide/styleguide.md#python
169
Karl Wiberge1d464e2017-09-08 13:12:36170## **Build files**
Karl Wibergee3d7602017-09-04 12:46:47171
Karl Wiberg91d0ab72017-09-07 15:05:31172The WebRTC build files are written in [GN][gn], and we follow
173the [Chromium GN style guide][chr-gn-style]. Additionally, there are
174some WebRTC-specific rules below; in case of conflict, they trump the
175Chromium style guide.
176
177[gn]: https://chromium.googlesource.com/chromium/src/tools/gn/
178[chr-gn-style]: https://chromium.googlesource.com/chromium/src/tools/gn/+/HEAD/docs/style_guide.md
179
Per Kjellandera7f2d842018-01-10 15:54:53180### <a name="webrtc-gn-templates"></a>WebRTC-specific GN templates
Karl Wiberg91d0ab72017-09-07 15:05:31181
182Use the following [GN templates][gn-templ] to ensure that all
183our [targets][gn-target] are built with the same configuration:
184
185instead of | use
186-----------------|---------------------
187`executable` | `rtc_executable`
188`shared_library` | `rtc_shared_library`
189`source_set` | `rtc_source_set`
190`static_library` | `rtc_static_library`
191`test` | `rtc_test`
192
193[gn-templ]: https://chromium.googlesource.com/chromium/src/tools/gn/+/HEAD/docs/language.md#Templates
194[gn-target]: https://chromium.googlesource.com/chromium/src/tools/gn/+/HEAD/docs/language.md#Targets
195
Per Kjellandera7f2d842018-01-10 15:54:53196### Target visibility and the native API
197
198The [WebRTC-specific GN templates](#webrtc-gn-templates) declare build
199targets whose default `visibility` allows all other targets in the
200WebRTC tree (and no targets outside the tree) to depend on them.
201
202Prefer to restrict the visibility if possible:
203
204* If a target is used by only one or a tiny number of other targets,
205 prefer to list them explicitly: `visibility = [ ":foo", ":bar" ]`
206* If a target is used only by targets in the same `BUILD.gn` file:
207 `visibility = [ ":*" ]`.
208
209Setting `visibility = [ "*" ]` means that targets outside the WebRTC
210tree can depend on this target; use this only for build targets whose
211headers are part of the [native API](native-api.md).
212
Karl Wibergee3d7602017-09-04 12:46:47213### Conditional compilation with the C preprocessor
214
215Avoid using the C preprocessor to conditionally enable or disable
Karl Wiberg91d0ab72017-09-07 15:05:31216pieces of code. But if you cant avoid it, introduce a GN variable,
Karl Wibergee3d7602017-09-04 12:46:47217and then set a preprocessor constant to either 0 or 1 in the build
218targets that need it:
219
220```
221if (apm_debug_dump) {
222 defines = [ "WEBRTC_APM_DEBUG_DUMP=1" ]
223} else {
224 defines = [ "WEBRTC_APM_DEBUG_DUMP=0" ]
225}
226```
227
228In the C, C++, or Objective-C files, use `#if` when testing the flag,
229not `#ifdef` or `#if defined()`:
230
231```
232#if WEBRTC_APM_DEBUG_DUMP
233// One way.
234#else
235// Or another.
236#endif
237```
238
239When combined with the `-Wundef` compiler option, this produces
240compile time warnings if preprocessor symbols are misspelled, or used
241without corresponding build rules to set them.