llvm.org GIT mirror llvm / 2d10d75
Made many paragraphs fit into 80 characters per line to avoid wrapping in an editor window. Re-worded confusing description about interdependence of modules. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@7374 91177308-0d34-0410-b5e6-96231b3b80d8 Misha Brukman 17 years ago
1 changed file(s) with 121 addition(s) and 40 deletion(s). Raw diff Collapse all Expand all
172172 }
173173

174174
175 ...which shuts gcc up. Any gcc warning that annoys you can be fixed by massaging the code appropriately.

176
177 These are the gcc warnings that I prefer to enable: -Wall -Winline -W -Wwrite-strings -Wno-unused

175 ...which shuts gcc up. Any gcc warning that annoys you can be
176 fixed by massaging the code appropriately.

177
178 These are the gcc warnings that I prefer to enable: -Wall -Winline
179 -W -Wwrite-strings -Wno-unused

178180
179181
180182
181183


Which C++ features can I use?

182184
183 Compilers are finally catching up to the C++ standard. Most compilers implement most features, so you can use just about any features that you would like. In the LLVM source tree, I have chosen to not use these features:

185 Compilers are finally catching up to the C++ standard. Most compilers implement
186 most features, so you can use just about any features that you would like. In
187 the LLVM source tree, I have chosen to not use these features:

184188
185189
186
  • Exceptions: Exceptions are very useful for error reporting and handling exceptional conditions. I do not use them in LLVM because they do have an associated performance impact (by restricting restructuring of code), and parts of LLVM are designed for performance critical purposes.

  • 187
    188 Just like most of the rules in this document, this isn't a hard and fast requirement. Exceptions are used in the Parser, because it simplifies error reporting significantly, and the LLVM parser is not at all in the critical path.

    189
    190
  • RTTI: RTTI has a large cost in terms of executable size, and compilers are not yet very good at stomping out "dead" class information blocks. Because of this, typeinfo and dynamic cast are not used.
  • 190
  • Exceptions: Exceptions are very useful for error reporting and handling
  • 191 exceptional conditions. I do not use them in LLVM because they do have an
    192 associated performance impact (by restricting restructuring of code), and parts
    193 of LLVM are designed for performance critical purposes.

    194
    195 Just like most of the rules in this document, this isn't a hard and fast
    196 requirement. Exceptions are used in the Parser, because it simplifies error
    197 reporting significantly, and the LLVM parser is not at all in the
    198 critical path.

    199
    200
  • RTTI: RTTI has a large cost in terms of executable size, and compilers are
  • 201 not yet very good at stomping out "dead" class information blocks. Because of
    202 this, typeinfo and dynamic cast are not used.
    191203

    192204
    193 Other features, such as templates (without partial specialization) can be used freely. The general goal is to have clear, consise, performant code... if a technique assists with that then use it.

    205 Other features, such as templates (without partial specialization) can be used
    206 freely. The general goal is to have clear, consise, performant code... if a
    207 technique assists with that then use it.

    194208
    195209
    196210
    197211


    Write Portable Code

    198212
    199 In almost all cases, it is possible and within reason to write completely portable code. If there are cases where it isn't possible to write portable code, isolate it behind a well defined (and well documented) interface.

    200
    201 In practice, this means that you shouldn't assume much about the host compiler, including its support for "high tech" features like partial specialization of templates. In fact, Visual C++ 6 could be an important target for our work in the future, and we don't want to have to rewrite all of our code to support it.

    213 In almost all cases, it is possible and within reason to write completely
    214 portable code. If there are cases where it isn't possible to write portable
    215 code, isolate it behind a well defined (and well documented) interface.

    216
    217 In practice, this means that you shouldn't assume much about the host compiler,
    218 including its support for "high tech" features like partial specialization of
    219 templates. In fact, Visual C++ 6 could be an important target for our work in
    220 the future, and we don't want to have to rewrite all of our code to support
    221 it.

    202222
    203223
    204224
    218238
    219239


    A Public Header File is a Module

    220240
    221 C++ doesn't do too well in the modularity department. There is no real encapsulation or data hiding (unless you use expensive protocol classes), but it is what we have to work with. When you write a public header file (in the LLVM source tree, they live in the top level "include" directory), you are defining a module of functionality.

    222
    223 Modules should be completely independent of each other, except for their dependence. A module is not just a class, a function, or a namespace: it's a collection of these that defines an interface. This interface may be several functions, classes or data structures, but the important issue is how they work together.

    224
    225
    226
    227 In general, a module should be implemented with one or more .cpp files. Each of these .cpp files should include the header that defines their interface first. This ensure that all of the dependences of the module header have been properly added to the module header itself, and are not implicit. System headers should be included after user headers for a translation unit.

    241 C++ doesn't do too well in the modularity department. There is no real
    242 encapsulation or data hiding (unless you use expensive protocol classes), but it
    243 is what we have to work with. When you write a public header file (in the LLVM
    244 source tree, they live in the top level "include" directory), you are defining a
    245 module of functionality.

    246
    247 Ideally, modules should be completely independent of each other, and their
    248 header files should only include the absolute minimum number of headers
    249 possible. A module is not just a class, a function, or a namespace:
    250 href="http://www.cuj.com/articles/2000/0002/0002c/0002c.htm">it's a collection
    251 of these that defines an interface. This interface may be several
    252 functions, classes or data structures, but the important issue is how they work
    253 together.

    254
    255
    260
    261 In general, a module should be implemented with one or more .cpp files.
    262 Each of these .cpp files should include the header that defines their
    263 interface first. This ensure that all of the dependences of the module header
    264 have been properly added to the module header itself, and are not implicit.
    265 System headers should be included after user headers for a translation unit.

    228266
    229267
    230268
    231269


    #include as Little as Possible

    232270
    233 #include hurts compile time performance. Don't do it unless you have to, especially in header files.

    234
    235 But wait, sometimes you need to have the definition of a class to use it, or to inherit from it. In these cases go ahead and #include that header file. Be aware however that there are many cases where you don't need to have the full definition of a class. If you are using a pointer or reference to a class, you don't need the header file. If you are simply returning a class instance from a prototyped function or method, you don't need it. In fact, for most cases, you simply don't need the definition of a class... and not #include'ing speeds up compilation.

    236
    237 It is easy to try to go too overboard on this recommendation, however. You must include all of the header files that you are using, either directly or indirectly (through another header file). To make sure that you don't accidently forget to include a header file in your module header, make sure to include your module header first in the implementation file (as mentioned above). This way there won't be any hidden dependencies that you'll find out about later...

    271 #include hurts compile time performance. Don't do it unless you have
    272 to, especially in header files.

    273
    274 But wait, sometimes you need to have the definition of a class to use it, or to
    275 inherit from it. In these cases go ahead and #include that header file. Be
    276 aware however that there are many cases where you don't need to have the full
    277 definition of a class. If you are using a pointer or reference to a class, you
    278 don't need the header file. If you are simply returning a class instance from a
    279 prototyped function or method, you don't need it. In fact, for most cases, you
    280 simply don't need the definition of a class... and not #include'ing
    281 speeds up compilation.

    282
    283 It is easy to try to go too overboard on this recommendation, however. You
    284 must include all of the header files that you are using, either directly
    285 or indirectly (through another header file). To make sure that you don't
    286 accidently forget to include a header file in your module header, make sure to
    287 include your module header first in the implementation file (as mentioned
    288 above). This way there won't be any hidden dependencies that you'll find out
    289 about later...

    238290
    239291
    240292
    241293


    Keep "internal" Headers Private

    242294
    243 Many modules have a complex implementation that causes them to use more than one implementation (.cpp) file. It is often tempting to put the internal communication interface (helper classes, extra functions, etc) in the public module header file. Don't do this. :)

    244
    245 If you really need to do something like this, put a private header file in the same directory as the source files, and include it locally. This ensures that your private interface remains private and undisturbed by outsiders.

    246
    247 Note however, that it's okay to put extra implementation methods a public class itself... just make them private (or protected), and all is well.

    295 Many modules have a complex implementation that causes them to use more than one
    296 implementation (.cpp) file. It is often tempting to put the internal
    297 communication interface (helper classes, extra functions, etc) in the public
    298 module header file. Don't do this. :)

    299
    300 If you really need to do something like this, put a private header file in the
    301 same directory as the source files, and include it locally. This ensures that
    302 your private interface remains private and undisturbed by outsiders.

    303
    304 Note however, that it's okay to put extra implementation methods a public class
    305 itself... just make them private (or protected), and all is well.

    248306
    249307
    250308
    256314
    257315


    Assert Liberally

    258316
    259 Use the "assert" function to its fullest. Check all of your preconditions and assumptions, you never know when a bug (not neccesarily even yours) might be caught early by an assertion, which reduces debugging time dramatically. The "<cassert>" header file is probably already included by the header files you are using, so it doesn't cost anything to use it.

    260
    261 To further assist with debugging, make sure to put some kind of error message in the assertion statement (which is printed if the assertion is tripped). This helps the poor debugging make sense of why an assertion is being made and enforced, and hopefully what to do about it. Here is one complete example:

    317 Use the "assert" function to its fullest. Check all of your
    318 preconditions and assumptions, you never know when a bug (not neccesarily even
    319 yours) might be caught early by an assertion, which reduces debugging time
    320 dramatically. The "<cassert>" header file is probably already
    321 included by the header files you are using, so it doesn't cost anything to use
    322 it.

    323
    324 To further assist with debugging, make sure to put some kind of error message in
    325 the assertion statement (which is printed if the assertion is tripped). This
    326 helps the poor debugging make sense of why an assertion is being made and
    327 enforced, and hopefully what to do about it. Here is one complete example:

    262328
    263329
    
                      
                    
    264330 inline Value *getOperand(unsigned i) {
    287353
    288354


    Prefer Preincrement

    289355
    290 Hard fast rule: Preincrement (++X) may be no slower than postincrement (X++) and could very well be a lot faster than it. Use preincrementation whenever possible.

    291
    292 The semantics of postincrement include making a copy of the value being incremented, returning it, and then preincrementing the "work value". For primitive types, this isn't a big deal... but for iterators, it can be a huge issue (for example, some iterators contains stack and set objects in them... copying an iterator could invoke the copy ctor's of these as well). In general, get in the habit of always using preincrement, and you won't have a problem.

    356 Hard fast rule: Preincrement (++X) may be no slower than postincrement (X++) and
    357 could very well be a lot faster than it. Use preincrementation whenever
    358 possible.

    359
    360 The semantics of postincrement include making a copy of the value being
    361 incremented, returning it, and then preincrementing the "work value". For
    362 primitive types, this isn't a big deal... but for iterators, it can be a huge
    363 issue (for example, some iterators contains stack and set objects in them...
    364 copying an iterator could invoke the copy ctor's of these as well). In general,
    365 get in the habit of always using preincrement, and you won't have a problem.

    293366
    294367
    295368
    296369


    Avoid endl

    297370
    298 The endl modifier, when used with iostreams outputs a newline to the output stream specified. In addition to doing this, however, it also flushes the output stream. In other words, these are equivalent:

    371 The endl modifier, when used with iostreams outputs a newline to the
    372 output stream specified. In addition to doing this, however, it also flushes
    373 the output stream. In other words, these are equivalent:

    299374
    300375
    
                      
                    
    301376 cout << endl;
    308383
    309384


    Exploit C++ to its Fullest

    310385
    311 C++ is a powerful language. With a firm grasp on its capabilities, you can make write effective, consise, readable and maintainable code all at the same time. By staying consistent, you reduce the amount of special cases that need to be remembered. Reducing the total number of lines of code you write is a good way to avoid documentation, and avoid giving bugs a place to hide.

    312
    313 For these reasons, come to know and love the contents of your local <algorithm> header file. Know about <functional> and what it can do for you. C++ is just a tool that wants you to master it. :)

    386 C++ is a powerful language. With a firm grasp on its capabilities, you can make
    387 write effective, consise, readable and maintainable code all at the same time.
    388 By staying consistent, you reduce the amount of special cases that need to be
    389 remembered. Reducing the total number of lines of code you write is a good way
    390 to avoid documentation, and avoid giving bugs a place to hide.

    391
    392 For these reasons, come to know and love the contents of your local
    393 <algorithm> header file. Know about <functional> and what it can do
    394 for you. C++ is just a tool that wants you to master it. :)

    314395
    315396
    316397