## Coding Style |
|
- **Indentation:** --- K&R only. |
- **Naming:** use small\_letters\_and\_underscore. Such names are much more |
readable. Same namging convention for class names, variables and functions. |
NeverUseUglyAndUnreadableCamelCasedCode. _Rationale_ -- readability. |
|
Prefer to use STL conventions. For example, for cleanup operations use `clear()`, for finding something "find()" and |
so on. |
- **Polish/Hungarian notations** are not in CppCMS. No prefixes or suffixes like `iNumber` or `m_some_class_member`. |
- **Variable Names:** --- variables like `i`, `j`, `tmp` are perfrectly well to use inside functions, in loops. |
It is ok to use `def`, `tmp` perfixes and suffixes for member variables when they meaning something. |
|
_Rationale:_ Linux Kernel Coding Style. |
|
- **Class Members:** are ended with underscore `_` with exception of public structure members that do not have suffixes/prefixes. Rationale - Boost. |
|
- **Tab Stops** --- Tab is 8, not 4, not 2 and defiantly not 5! Tab width=8 is like Pi=3.1415926535. Do not use something |
else. This is most compatible over different editors, it is standard, it should be used anywhere. It makes code more |
readable at 1:00am. |
|
Do not replace tabs with spaces, all indentation should be done with tabs. |
|
_Rationale:_ Linux Kernel Coding Style |
|
- **Preprocessor Macros** --- should be CAPITAL\_CASED\_WITH\_UNDERSCORES. Always add `CPPCMS_` prefix to them. |
|
|
## Keeping backward compatible ABI |
|
TODO. |
|
## General Coding Notes |
|
### Exceptions |
|
All code you write should be exception safe. Only functions that you may assume they never throw exceptions are POSIX API or 3rd party C libraries like libgcrypy or sqlite3. Even STL may throw exception. Assume that std::bad\_alloc may be thrown and handle it correctly. |
|
Thus: |
|
- Always use smart pointers. Prefer auto\_ptr over reference counting smart pointers: |
|
1. It is faster and does not include ref-counting overheads |
2. All of them can be always created from auto\_ptr but not in other direction. |
3. It has move semantics that covers our requirements in most of cases: |
|
For example |
|
auto_ptr<my_class> my_func() |
{ |
auto_ptr<my_class> instance(new my_class); |
instance->do_something(); |
return instance; |
} |
|
- Use std::vector instead of allocating `new some_class[N]`. |
- When using C API, that does not have destructors, put your code inside try-catch block and cleanup everything. |
- If you use C API in more then one place consider wrapping it with simple class or at least provide scoped destructor. See as an example posix\_mutex.h or fcntl\_mutex.h |
|
### STL |
|
Do not reinvent the wheel, use STL --- it is well document, well known, highly available library that does the job. Use it. |
|
_Notes:_ |
|
1. Always prefer std::vector to std::list --- it has better performance because it is cache friendly. |
2. Always prefer std:string for text storage. |
3. It is OK to return STL collections from functions, compiler know how to optimize them. |
4. Do not forget `swap()` function --- it can save lot's of unnecessary copies for you. For example: |
|
vector<char> foo(); |
... |
void bar() |
{ |
vector<char> s; |
for(;;) { |
s.swap(foo()); |
// Not s=foo(); |
if(s.empty()) |
break; |
} |
} |
|
Description: when you call `s=foo()` assignment operator is called that copies the value that `foo()` returned to `s` and then releases it. When you call `s.swap(foo())` the value in `s` is replaced by returned value and the old value in `s` is cleaned --- you saved copy of probably huge buffer, you operation is done in `O(1)`. |
5. If you have non-copyable class, you can store it in STL collection using reference counting pointer. |
|
## Libraries |
|
### Boost |
|
CppCMS should work with at least Boost 1.37. |
CppCMS should work with at least Boost 1.36. |
|
Generally prefer boost over other libraries, however use Boost features carefully, or do not use at all. Examples: |
|
1. Boost Interprocess too "heavy" and little bit "ugly" because it supports windows and supports placing any objects in memory. The nature of `fork()` gives much better functionality and allows placing any object in shared memory every time it use shared memory allocators. |
|
So use it only as replacement of libmm. |
|
3. Boost Serialization -- has too many performance overheads -- don't use it. |
|
### Licenses |
|
1. All libraries should be OpenSource libraries |
2. Prefer non-copyleft licenses like MIT, 3 clause BSD, Boost over copyleft one, like LGPL. |
3. All libraries, CppCMS uses should be compatible with LGPLv2. |
4. You may use strong copyleft libraries for stand alone utilities that are not linked with CppCMS framework. |
|
For example: If you want to write GUI for `cppcms_tcp_scale` utility using Qt you are welcome. |
|
|
### Using |
|
If you want to add an additional dependency for CppCMS make sure: |
|
1. Check if boost has implementation of such feature. |
1. There is a big value for adding such dependency. |
2. This library is highly available. |
3. You checked all alternatives and decided that this one is the best. |
4. You had added an autoconf macro and conditional build for CppCMS that allows building all framework without this library. |
|
For example, libgcrypt: |
|
- You need high quality library to encrypt cookies, home made solutions are too dangerous. |
- This library is available for almost any UNIX platform. |
- Other alternatives like OpenSSL has problematic license and bad documentation. |
- If you do not have libgcrypt, you still have simple digitally signed cookies that are still safe. |
|
|