blob: 7345067dd62873741bf7b75d7087e67fe67ad7a4 [file] [log] [blame] [view]
David Ghandeharifd767342017-02-13 12:56:12 -08001# Starboard C and C++ Style Guide
2
3A description of the coding conventions for Starboard code and API headers.
4
5**Status:** REVIEWED\
6**Created:** 2016-11-08
7
8Starboard generally tries to follow the coding conventions of Cobalt, which
9itself mostly follows the conventions of Chromium, which mostly follows the
10externally-published Google C++ coding conventions. But, Starboard has some
11special requirements due to its unusual constraints, so it must add a few new
12conventions and loosen some of the existing style prescriptions.
13
14## Background
15
16Before looking at this document, bear in mind that it is not intending to
17completely describe all conventions that apply to Starboard. You probably want
18to take some time to familiarize yourself with these documents first, probably
19in this order:
20
21 * [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html)
22 * [Chromium C++ Style Guide](https://chromium.googlesource.com/chromium/src/+/master/styleguide/c++/c++.md)
23 * [Cobalt Style Guide](http://cobalt.foo/broken)
24
25The main additional constraints that Starboard has to deal with are:
26
27 * The Starboard API is defined in straight-C. It must be able to interface
28 with all possible third-party components, many of which are in C and not
29 C++.
30 * Starboard is a public API. Starboard platform implementations and
31 applications written on top of Starboard will change independently. This
32 means there are intense requirements for API stability, usage
33 predictability, searchability, and documentation.
34 * Note that even though it is presented as a "style guide," the conventions
35 presented here are required to be approved for check-in unless otherwise
36 noted.
37
38
39## Definitions
40
41### snake-case
42
43Words separated with underscores.
44
45 lower_snake_case
46 ALL_CAPS_SNAKE_CASE
47
48### camel-case
49
50Words separated by letter capitalization.
51
52 camelCase
53 CapitalizedCamelCase
54
55## C++ Guidelines
56
57What follows are hereby the guidelines for Starboard C and C++ code. Heretofore
58the guidelines follow thusly as follows.
59
60### API Definitions
61
62 * Starboard API definitions must always be compatible with straight-C99 compilers.
63 * All public API declarations must be specified in headers in
64 `src/starboard/*.h`, not in any subdirectories.
65 * Non-public declarations must NOT be specified in headers in
66 `src/starboard/*.h`.
67 * C++ inline helper definitions may be included inside an `#if
68 defined(__cplusplus)` preprocessor block. They must only provide
69 convenience, and must NOT be required for any API functionality.
70 * All public API functions should be exported symbols with the SB_EXPORT
71 attribute.
72 * No non-const variables shall be exposed as part of the public API.
73 * All APIs should be implemented in C++ source files, not straight-C source files.
74
75### Modules
76
77 * Each module header must be contained with a single header file.
78
79 * The name of the module must be the singular form of the noun being
80 interfaced with by the module, without any "sb" or "starboard".
81 * `file.h`
82 * `directory.h`
83 * `window.h`
84 * Module interfaces should not have circular dependencies.
85
86### File Names
87
88 * Like in the other conventions (e.g. Google, Chromium), file names must be in
89 `lower_snake_case`.
90 * File names must not contain `sb_` or `starboard_`.
91 * The name of a module header file must be the `lower_snake_case` form of the
92 module name.
93 * `SbConditionVariable` `starboard/condition_variable.h`
94 * A header that is intended to be an internal implementation detail of one or
95 more platform implementations should have the suffix `_internal.h`, and
96 include the header `starboard/shared/internal_only.h`.
97 * See "Implementations" for conventions about where to place implementation files.
98
99### Types
100
101 * Like in the other conventions, types should be `CapitalizedCamelCase`.
102 * Every public Starboard type must start with `Sb`. There are no namespaces in
103 C, so `Sb` is the Starboard namespace.
104 * Every public Starboard type must be declared by a module, and must have the
105 name of the module following the `Sb`.
106 * `file.h` contains `SbFile`, `SbFileInfo`, `SbFileWhence`, etc...
107 * Every seemingly-allocatable, platform-specific Starboard type should be
108 defined as an opaque handle to a publically undefined struct with the
109 `Private` suffix. Follow this pattern for all such type declarations.
110 * `struct SbFilePrivate` is declared, but not defined in the public header.
111 * `SbFilePrivate` is `typedef`'d to `struct SbFilePrivate`. This is a C
112 thing where types are defined as names with the "`struct`" keyword
113 prepended unless `typedef`'d.
114 * `SbFile` is defined as a `typedef` of `struct SbFilePrivate*`.
115 * C structs may be defined internally to have functions and visibility. It is
116 allowed for such structs to have constructors, destructors, methods,
117 members, and public members.
118 * It is also considered idiomatic to never define the private struct but to
119 just treat it like a handle into some other method of object tracking,
120 casting the handle back and forth to the pointer type.
121 * If a word in the name of a type is redundant with the module name, it is
122 omitted.
123 * A monotonic time type in the Time module is `SbTimeMonotonic`, not
124 ~~`SbMonotonicTime`, `SbTimeMonotonicTime`, or
125 `SbTimeMonotonicSbTime`~~.
126
127### Functions
128
129 * Like in the other conventions, functions should be `CapitalizedCamelCase`.
130 * Every public Starboard function must start with `Sb`. There are no namespaces
131 in C, so `Sb` is the Starboard namespace.
132 * Every public Starboard function must be declared by a module, and must have
133 the name of the module following the `Sb`.
134 * `system.h` contains `SbSystemGetPath()`
135 * `file.h` contains `SbFileOpen()`
136 * After the Starboard and Module prefix, functions should start with an
137 imperative verb indicating what the function does.
138 * The Thread module defines `SbThreadCreateLocalKey()` to create a key for
139 thread local storage.
140 * If a word in the name of a function is redundant with the module name, it is
141 omitted.
142 * The `File` module as the function `SbFileOpen`, not ~~`SbOpenFile`,
143 `SbFileOpenFile` or `SbFileOpenSbFile`~~.
144 * If this gets awkward, it may indicate a need to split into a different
145 module.
146
147### Variables, Parameters, Fields
148
149 * Like in the other conventions, variable, function parameter, and field names
150 must be in `lower_snake_case`.
151 * Private member fields end in an underscore.
152 * Public member fields do not end in an underscore.
153
154### Namespaces
155
156Most Starboard API headers are straight-C compatible, so cannot live inside a
157namespace. Implementations, since they implement straight-C interface functions,
158also cannot live inside a namespace.
159
160But, in all other cases, Starboard C++ code should follow the inherited
161conventions and use a namespace for each directory starting with a "starboard"
162namespace at the starboard repository root.
163
164### Preprocessor Macros
165
166 * Like in the other conventions, variable, function parameter, and field names
167 must be in `ALL_CAPS_SNAKE_CASE`.
168 * Macros may be used as compile-time constants because straight-C does not
169 have a proper facility for typed constants. This is as opposed to macros
170 used primarily at preprocessor-time to filter or modify what gets sent to
171 the compiler. Macros used as compile-time constants and that are not
172 configuration parameters should be explicitly-typed with a c-style cast, and
173 should follow the Constants naming conventions.
174 * Macros must start with `SB_`, and then must further be namespaced with the
175 module name, with the exception of configuration definitions.
176 * Configuration definitions should be namespaced with the module name that
177 they primarily affect, if applicable, or a scope that generally indicates
178 its domain.
179 * `SB_FILE_MAX_NAME`
180 * `SB_MEMORY_PAGE_SIZE`
181 * Always use `#if defined(MACRO)` over `#ifdef MACRO`.
182
183### Constants
184
185 * Constants (including enum entries) are named using the Google constant
186 naming convention, `CapitalizedCamelCase`d, but starting with a lower-case
187 `k`.
188 * After the `k`, all constants have `Sb`, the Starboard namespace.
189 * `kSb`
190 * After `kSb`, all constants then have the module name.
191 * `kSbTime`
192 * `kSbFile`
193 * After `kSb<module>` comes the rest of the name of the constant.
194 * `kSbTimeMillisecond`
195 * `kSbFileInvalid`
196 * Enum entries are prefixed with the full name of the enum.
197 * The enum `SbSystemDeviceType` contains entries like
198 `kSbSystemDeviceTypeBlueRayDiskPlayer`.
199
200### Comments
201
202 * All files must have a license and copyright comment.
203 * It is expected that the straight-C compiler supports C99 single-line
204 comments. Block comments should be avoided whenever possible, even in
205 license and copyright headers.
206 * Each public API module file should have a Module Overview documentation
207 comment below the license explaining what the module is for, and how to use
208 it effectively.
209 * The Module Overview must be separated by a completely blank line from the
210 license comment.
211 * The first line of the Module Overview documentation comment must say
212 "`Module Overview: Starboard <module-name> module`", followed by a blank
213 comment line (i.e. a line that contains a `//`, but nothing else).
214 * The first sentence of a documentation comment describing any entity (module,
215 type, function, variable, etc...) should assume "This module," "This type,"
216 "This function," or "This variable" at the beginning of the sentence, and
217 not include it.
218 * The first sentence of a documentation comment describing any entity should
219 be a single-sentence summary description of the entire entity.
220 * The first paragraph of a documentation comment should describe the overall
221 behavior of the entity.
222 * Paragraphs in comments should be separated by a blank comment line.
223 * All public entities must have documentation comments, including enum
224 entries.
225 * Documentation comments should be formatted with Markdown.
226 * Variables, constants, literals, and expressions should be referenced in
227 comments with pipes around them.
228 * All comments must be full grammatically-correct English sentences with
229 proper punctuation.
230
231### Implementations
232
233 * Each API implementation should attempt to minimize other platform
234 assumptions, and should therefore use Starboard APIs to accomplish
235 platform-specific work unless directly related to the platform functionality
236 being implemented.
237 * For example, `SbFile` can use POSIX file I/O, because that what it is
238 abstracting, but it should use `SbMemoryAllocate` for any memory
239 allocations, because it might be used with a variety of `SbMemory`
240 implementations.
241 * Whenever possible, each shared function implementation should be implemented
242 in an individual file so as to maximize the chances of reuse between
243 implementations.
244 * This does not apply to platform-specific functions that have no chance of
245 being reusable on other platforms.
246 * Implementation files that can conceivably be shared between one or more
247 implementations should be placed in a `starboard/shared/<dependency>/`
248 directory, where `<dependency>` is the primary platform dependency of that
249 implementation. (e.g. `libevent`, `posix`, `c++11`, etc.)
250 * Implementation files that don't have a specific platform dependency, but
251 whether to use them should be a platform decision should be placed in
252 `starboard/shared/starboard/`, and must only have dependencies on other
253 Starboard APIs.
254 * Implementation files that definitely can be common to ALL implementations
255 should be placed in `starboard/common/`.
256
257### Language Features
258
259 * In public headers, particularly in inline functions and macros, only C-Style
260 casts may be used, though they are forbidden everywhere else.
261 * It is expected that the C compiler supports inline functions. They must be
262 declared `static`, and they must use the `SB_C_INLINE` or
263 `SB_C_FORCE_INLINE` attribute. In straight-C code, there is no anonymous
264 namespace, so `static` is allowed and required for inline functions.
265 * No straight-C ISO or POSIX headers should be assumed to exist. Basic C++03
266 headers may be assumed to exist in C++ code. The ISO C standards have grown
267 up over a long period of time and have historically been implemented with
268 quirks, missing pieces, and so on. Support for the core C++ standard library
269 is much more consistent on those platforms that do support it.
270 * It is idiomatic to include thin C++ inline wrappers inside public API
271 headers, gated by an `#if defined(cplusplus__)` check.