c++development

Best Practices for C++ Development

Spread the love

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

  • Const as Much as Possible : const tells the compiler that a variable or method is immutable. This helps the compiler optimize the code and helps the developer know if a function has a side effect. Also, using const & prevents the compiler from copying data unnecessarily.
  • Carefully Consider Your Return Types : Returning by & or const & can have significant performance savings when the normal use of the returned value is for observation Returning by value is better for thread safety and if the normal use of the returned value is to make a copy anyhow, there's no performance lost If your API uses covariant return types, you must return by & or *. For temporaries and local variables Always return by value.
  • Do not pass and return simple types by const ref: Because passing and returning by reference leads to pointer operations instead of much more faster-passing values in processor registers.
  • Avoid Raw Memory Access.
  • Use std::array or std::vector Instead of C-style Arrays.
  • Use Exceptions: Exceptions cannot be ignored. Return values, such as using boost:: optional, can be ignored and if not checked can cause crashes or memory errors. An exception, on the other hand, can be caught and handled.
  • Do not define a variadic function : Variadic functions can accept a variable number of parameters. The probably best-known example is printf(). You have the possibility to define this kind of functions by yourself but this is a possible security risk. The usage of variadic functions is not type safe and the wrong input parameters can cause a program termination with an undefined behavior.

  • 4. Considering Maintainability

  • Avoid Compiler Macros: Compiler definitions and macros are replaced by the preprocessor before the compiler is ever run. This can make debugging very difficult because the debugger doesn't know where the source came from.
  • Consider Avoiding Boolean Parameters: They do not provide any additional meaning while reading the code. You can either create a separate function that has a more meaningful name, or pass an enumeration that makes the meaning more clear
  • Avoid Raw Loops.
  • Properly Utilize 'override' and 'final' : These keywords make it clear to other developers how virtual functions are being utilized, can catch potential errors if the signature of a virtual function change, and can possibly hint to the compiler of optimizations that can be performed.

  • 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

  • Avoid Global Data : Global data leads to unintended side effects between functions and can make code difficult or impossible to parallelize. Even if the code is not intended today for parallelization, there is no reason to make it impossible for the future.
  • Statics: Besides being global data, statics are not always constructed and deconstructed as you would expect. This is particularly true in cross-platform environments.
  • Shared Pointers : std::shared_ptr is "as good as a global" (http://stackoverflow.com/a/18803611/29975) because it allows multiple pieces of code to interact with the same data.
  • Singletons : A singleton is often implemented with a static and/or shared_ptr.
  • Avoid Heap Operations : Much slower in threaded environments. In many or maybe even most cases, copying data is faster. Plus with move operations and such and things.

  • 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

    What OdiTek offers


    Refer our Skills page:

    C++ Development

    C++ is one of the most popular object-oriented programming language that is used for multi-device and multi-platform enterprise-class large scale performance -driven application development. The C++ language combines increased capacity and optimal performance of software that is why it is widely used for building well-organized...

    more

    Client Testimonials

    We had a tough deadline to launch our .Net based application that processes a lot of data, and got very frustrated with our development agency we hired. Fortunately we got Oditek, and they took over seamlessly the product development, launched the app & continued feature development. Just awesome!

    Neal Bonrud

    Co-Founder – SubScreener, USA

    They were very attentive to our needs as clients and went out of the way to make sure our projects were taken care of. They were always able to get projects done in the specifications we requested. They are passionate about getting things done; I would definitely recommend them to lead any IT projects.

    Dann Manahan

    Sr VP Technology- 1031 Crowd Funding

    I worked with OdiTek on few high profile banking application projects. They did a fantastic job with web applications & manual testing on the VAS apps for two leading banks of UK that included rigorous UAT phases. I recommend them for any application development where security matters.

    Clive Shirley

    CTO- Smarta, UK

    OdiTek is our extended team who works on our key software projects. They are dependable, good in collaboration and technically very much to the level what we expect a global team should be. They had transformed our web applications, CRM and added mobility to existing business platforms here.

    Matt Berry

    IT Manager- First Option Online

    It's been more than 4 years now that we are working with OdiTek on our cloud based web product development. It's been amazing working together, they are very competent on designing scalable, high performance apps. Their technical support is outstanding to say the least, even at odd hours.

    Brad Taylor

    CEO- BluesummitTech, USA

    I am a fan of Team OdiTek since 2014 and have worked on many product development projects together. Specially worth mentioning their deliveries on VAS Banking web application development & manual testing services for Smarta, UK. They are highly skilled & a professional team to work with.

    Tom Bowden

    Digital Propositions - HSBC, London

    OdiTek has been working on our Integrated Web-scale Mobile Platform i.e. Optimal Health since 2014. They are very professional and takes care of the requirements meticulously. They are technically very sound and sincere in ensuring quality & performance. Wonderful working with them!

    Catherine Lim

    COO- Medilink Global Sdn Bdh

    You can trust the team, with minimum supervision you get the work done. They are honest, professional & committed to schedule & quality. I had been successfully running 3 business applications designed, developed and maintained by Oditek developers. It’s been a pleasure working with them.

    Scott Evans

    CEO- Pink Storage, UK

    OdiTek has been working in custom software development, including services for test automation. Many of them have worked with me in 2009-10 when I was R&D Manager in NetHawk India. They have great enthusiasm & a passion to excel in bringing customer success. Their work has been very impressive.

    Karen Hamber

    Senior Product Manager- Skype

    It's amazing to see these guys are turning their experience into a global delivery excellence at OdiTek. I am sure their past large scale product development experience will be handy to product companies. I would always recommend Oditek for software development, especially performance-driven solutions.

    Juha Marjeta

    Opti Automation Oyj

    If you need additional information or have project requirements, kindly drop an email to: info@oditeksolutions.com

    ×