1. Use the Tools Available
In the early phase of the development process, an automated framework needs to define for source code management, build, execute and test. It should not take more than 2-3 commands to check out the source code, build, and execute the tests. Various tools are available for this purpose.
1.1.Source Control Tools:
- GitHub – allows for unlimited public repositories, must pay for a private repository.
- Bitbucket – allows for unlimited private repositories with up to 5 collaborators, for free.
- SourceForge – open source hosting only.
- GitLab – allows for unlimited public and private repositories, unlimited CI Runners
included, for free. - Visual Studio Online – allows for unlimited public repositories, must pay for private repository
1.2.Build Tool
- Use an industry standard widely accepted build tool. This prevents you from reinventing the wheel whenever you discover / link to a new library / package your product / etc. Some examples are CMake, Conan, FASTBuild, CPPAN, Ninja, etc.
1.3.Continuous Integration
- Continuous Integration (CI) tools automatically build the source code as changes are pushed to the repository.
- Travis CI: works well with C++. Designed for use with GitHub. Free for public repositories on GitHub.
- AppVeyor: Supports Windows, MSVC and MinGW, Free for public repositories on GitHub.
- Hudson CI / Jenkins CI: Java Application Server is required supports Windows, OS X, and Linux extendable with a lot of plugins.
- Visual Studio Online: Tightly integrated with the source repositories from Visual Studio Online
1.4.Compilers
- Use every available and reasonable set of warning options. Some warning options only work with optimizations enabled, or work better the higher the chosen level of optimization is, for example -Wnull-dereference with GCC.
You should use as many compilers as you can for your platform(s). Each compiler implements the standard slightly differently and supporting multiple will help ensure the most portable, most reliable code.
1.5.Static Analyzers
-
Use the static analyzer to run as part of your automated build system. Cppcheck and clang tools could meet the requirement as free tools.
1.6.Runtime Checkers
- Memory usage validators: Runtime code analyzer that can detect memory leaks, race conditions, and other associated problems. Some of the good tools are Valgrind, Dr Memory, etc.
- Code Coverage Analysis : A coverage analysis tool shall be run when tests are executed to make sure the entire application is being tested. Some of the good tools are Codecov, Coveralls, LCOV etc.
1.7.Testing Tools
- Make sure whatever build system you use has a way to execute tests built in. To further aid in executing tests, consider a library such as Google Test, Catch, CppUTest or Boost.Test to help you organize the tests.
2. Style
Consistency is the most important aspect of style. The most important aspect is following a style that the average C++ programmer is used to reading. So, establish a style guideline. Define the guideline for the areas like Common Naming Conventions, Distinguish Private Object Data, Distinguish Function Parameters, Comments formats, Block definition formats, etc.
3. Considering Safety
Avoid Raw Memory Access.
4. Considering Maintainability
Avoid Raw Loops.
5. Considering Portability
Know Your Types : Most portability issues that generate warnings are because we are not careful about our types. Standard library and arrays are indexed with size_t . Standard container sizes are reported in size_t . If you get the handling of size_t wrong, you can create subtle lurking 64-bit issues that arise only after you start to overflow the indexing of 32-bit integers. char vs unsigned char.
6. Considering Threadability
7. Considering Performance
7.1.Build Time
- Forward Declare When Possible.
- Avoid Unnecessary Template Instantiation : Templates are not free to instantiate. Instantiating many templates, or templates with more code than necessary increases compiled code size and build time.
- Avoid Recursive Template Instantiations.
- Don’t Unnecessarily Include Headers : The compiler has to do something with each include directive it sees. Even if it stops as soon as it seems the #ifndef include guard, it still had to open the file and begin processing it.
- Consider using precompiled headers.
7.2.Runtime
- Analyze the Code to find out real bottlenecks.
- Simplify the Code.
- Use Initializer Lists: Initializer lists are significantly more efficient; reducing object copies and resizing of containers.
- Reduce Temporary Objects.
- Enable move operations : Move operations are one of the most touted features of C++11. They allow the compiler to avoid extra copies by moving temporary objects instead of copying them in certain cases
- Kill shared_ptr Copies : shared_ptr objects are much more expensive to copy than you’d think they would be. This is because the reference count must be atomic and thread-safe.
- Reduce Copies and Reassignments as Much as Possible.
- Avoid Excess Exceptions
- Get rid of “new” : We already know that we should not be using raw memory access, so we are using unique_ptr and shared_ptr instead.
- Get rid of std::endl : std::endl implies a flush operation. It’s equivalent to “\n” << std::flush.
- Limit Variable Scope : Variables should be declared as late as possible, and ideally only when it’s possible to initialize the object. Reduced variable scope results in less memory being used, more efficient code in general, and helps the compiler optimize the code further.
- Prefer double to float , But Test First : Depending on the situation and the compiler’s ability to optimize, one may be faster over the other. Choosing float will result in lower precision and may be slower due to conversions. On vectorizable operations float may be faster if you are able to sacrifice precision.
Prefer ++i to i++ : Pre-increment is faster than post-increment because it does not require a copy of the object to be made.
Conclusion
Whenever there is a need for performance-driven enterprise class product development, C++ is widely recognized as a choice by default. Variety of applications use C++ programming, and at OdiTek we have a pool of vastly experienced CPP developers. We will be happy to assist you to plan & do product development, drop us an email on info@oditeksolutions.com