Project

General

Profile

Actions

Best Practises » History » Revision 2

« Previous | Revision 2/3 (diff) | Next »
quintus, 04/17/2021 08:35 PM
Add section about system-specific conditional compilation


Best Practises

This page is a list of practises usually followed in the project's code base.

Character encoding (charset) of strings

C++ does not have a defined encoding (charset, character set) for its string types, most notably std::string. It is thus required to always be aware of what encoding a string is in. This project uses std::string as its main string type (as opposed to std::wstring) and ensures that the character encoding used in this strings is UTF-8. When interfacing with other software, conversion is applied as required. For example, if a programming library returns strings that are not in UTF-8, they are immediately converted to UTF-8 before storing them for later use. The Win32 API as the most prominent example uses UTF-16LE for example, thus interacting with it requires conversion from and to the UTF-8-encoded std::string instances used in this project.

Likewise, all files written by the programme are written in UTF-8, regardless of the platform. BOMs (byte order marks) are not to be used.

Type for filesystem pathes

Use C++17's std::filesystem::path for dealing with pathes on the filesystem. Use std::filesystem::u8path() to create an instance of std::filesystem::path from an std::string encoded in UTF-8.

Inclusion of STL and other namespaces

In header files, do not include the std namespace or any other namespace, but write it out in full. This is to prevent unexpected namespace changes on #include.

In implementation files, do include the std namespace. Include other namespaces if it is useful and adds to the readability. Inclusion of namespaces should normally be done towards the beginning of a .cpp file, though it might be useful to only include a namespace in a single function. Use readability as the goal for decision.

The std::filesystem namespace is annoying to type even with std included. In .cpp files, abbreviate it as fs like this:

namespace fs = std::filesystem;
// Now you can access std::filesystem::path more
// easily as fs::path.

System-specific conditional compilation

When implementing system-specific code, use an #if/#elsif/#else preprocessor block. The #else block should always give the compilation error message "unsupported system" (by using the #error preprocessor directive). This eases porting of the software to new platforms, because every system-specific code section will cause a compilation error on new platforms. The porting developer can then look at that and adapt the statements as necessary one by one.

Example:

#if defined(_WIN32)
// Windows-specific code
#elsif defined(__unix__)
// Unix-specific code
#else
#error Unsupported system
#endif

There is a list of system-specific compiler macros available.

Updated by quintus over 3 years ago · 2 revisions