## 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.
|
|
|