Skip to main content

Secondary navigation

  • Downloads
  • Integrations
  • Blog
  • Company
    • About Us
    • Team
    • Culture
    • Careers
    • Partners
    • Press
    • Events
    • Security & Compliance
  • Contact
    • Contact Us
    • Request Support
    • Subscribe
  • Language
    • English
    • 日本語
    • 简体中文
    • 한국어
Home
Perforce

Main Navigation - Mega Menu

  • Products

    Main Navigation - Mega Menu

    • Explore Products
    • All Products
    Helix Core
    Version Control
    Helix TeamHub
    Code Hosting for Git, SVN, Hg
    Methodics IPLM
    IP Lifecycle Management
    Gliffy
    Diagramming
    JRebel
    Java Application Development
    Helix DAM
    Digital Asset Management
    Helix Core
    Version Control
    Helix TeamHub
    Code Hosting for Git, SVN, Hg
    Methodics IPLM
    IP Lifecycle Management
    Gliffy
    Diagramming
    JRebel
    Java Application Development
    Helix DAM
    Digital Asset Management
  • Solutions

    Main Navigation - Mega Menu

    • Explore Solutions
    • Solutions Overview

    Main Navigation - Mega Menu

    • By Need
    • By Industry

    Main Navigation - Mega Menu

    • Application Lifecycle Management
    • Agile Project Management
    • Diagramming
    • DevOps
    • Version Control
    • IP Lifecycle Management
    • Java Application Development
    • Web & Mobile App Testing
    • Codeless Selenium Automation
    • Static Analysis & SAST
    • Audit & Compliance
    • API Management
    • Open Source Support
    • Enterprise PHP
    • HPC Debugging
    • Development Tools & Libraries

    Main Navigation - Mega Menu

    • Aerospace & Defense
    • Automotive
    • Embedded Systems
    • Semiconductor
    • Energy
    • Financial
    • Game Development
    • Virtual Production
    • Government
    • Medical Devices
    • Software
    • Digital Twins

    Main Navigation - Mega Menu

    Main Navigation - Mega Menu

    Main Navigation - Mega Menu

    Main Navigation - Mega Menu

  • Customers
  • Resources

    Main Navigation - Mega Menu

    • Explore Resources
    • Papers & Videos
    • Recorded Webinars
    • Events & Webinars
    • Blog
    • Free Trials
    • Subscribe
    Version Control in Virtual Production

    Version Control in Virtual Production Field Guide

    Read Now
  • Support
  • Services

    Main Navigation - Mega Menu

    • Consulting/Professional Services
    • Training

    Main Navigation - Mega Menu

    • Consulting Services Overview
    • Akana
    • BlazeMeter
    • Helix ALM
    • Helix Core
    • Helix QAC
    • Klocwork
    • Methodics IPLM
    • OpenLogic
    • Perfecto
    • Zend

    Main Navigation - Mega Menu

    • Training Overview
    • Hansoft
    • Helix ALM
    • Helix Core
    • Helix QAC
    • Klocwork
    • OpenLogic
    • Perfecto
    • Zend
  • Try Free
  • Downloads
  • Integrations
  • Blog
  • Company

    Main Navigation - Mega Menu

    • About Us
    • Careers
    • Culture
    • Events
    • Partners
    • Press
    • Team
  • Contact

Version 4.0

High Integrity C++ Coding Standard

Released October 3, 2013

Request PDF Version
High Integrity C++ Coding Standard
0. Introduction
1. General
2. Lexical Conventions
3. Basic Concepts
4. Standard Conversions
5. Expressions
6. Statements
7. Declarations
8. Definitions
9. Classes
10. Derived Classes
11. Member Access Control
12. Special Member Functions
13. Overloading
14. Templates
15. Exception Handling
16. Preprocessing
17. Standard Library
18. Concurrency
19. References
20. Revision History
21. Conditions of Use

8. Definitions

8.1 Type Names


8.1.1 Do not use multiple levels of pointer indirection

In C++, at most one level of pointer indirection combined with references is sufficient to express any algorithm or API. Instead of using multidimensional arrays, an array of containers or nested containers should be used. Code reliant on more than one level of pointer indirection will be less readable and more difficult to maintain.

#include <cstdint>                          
#include <vector>
               
void foo (int32_t const * const * const pp); // @@- Non-Compliant [email protected]@
void foo (int32_t const * const & rp);       // @@+ Compliant [email protected]@
void foo (int32_t const (& ra) [10]);        // @@+ Compliant [email protected]@
void foo (std::vector <int32_t> const & rv); // @@+ Compliant [email protected]@


Exception

Use of argv in the main function is allowed.

For example:

// main1 .cpp
// Compliant: argv not used
int main ();
// main2 .cpp
// Compliant: 2 levels of pointer indirection in argv
int main (int argc , char * argv []);
// main3 .cpp
// Compliant: 2 levels of pointer indirection in argv
int main (int argc , char * * argv );


References

  • JSF AV C++ Rev C – 169
  • JSF AV C++ Rev C – 170
  • MISRA C++:2008 – 5-0-19

View references >

8.2 Meaning of Declarators


8.2.1 Make parameter names absent or identical in all declarations

Although the C++ standard does not mandate that parameter names match in all declarations of a function (e.g. a declaration in a header file and the definition in the main source file), it is good practice to follow this principle.

#include <cstdint>
                                       
void read (int32_t * buffer, int32_t * size);
               
void read (int32_t * size, int32_t * buffer) // @@- Non-Compliant [email protected]@
{
}
     
class B
{
public:
virtual void foo (int32_t in) = 0;
};
               
class C : public B
{
public:
void foo (int32_t) override  // @@+ Compliant [email protected]@
{
}
};

References

  • HIC++ v3.3 – 11.3

View references >

8.2.2 Do not declare functions with an excessive number of parameters

A function defined with a long list of parameters often indicates poor design and is difficult to read and maintain. The recommended maximum number of function parameters is six.

#include <cstdint>
#include <vector>
               
// @@- Non-Compliant: 7 parameters [email protected]@
void foo (int32_t mode
, int32_t const * src
, int32_t src_size
, int32_t * dest
, int32_t dest_size
, bool padding
, bool compress);
               
// @@+ Compliant [email protected]@
void foo (int32_t flags
, std::vector <int32_t> const & src
, std::vector <int32_t> & dest);

References

  • HIC++ v3.3 – 4.3

View references >

8.2.3 Pass small objects with a trivial copy constructor by value

Because passing by const reference involves an indirection, it will be less efficient than passing by value for a small object with a trivial copy constructor.

#include <cstdint>
   
class C
{
public:
C (C const &) = default; // trivial copy constructor
   
private:
int32_t m_i;
int32_t m_j;
};
               
void foo (C v)   // @@+ Compliant [email protected]@
{
}
   
class D
{
public:
D (D const &); // non-trivial (user defined) copy constructor
   
private:
int32_t m_i;
int32_t m_j;
};
               
void foo (D v)   // @@- Non-Compliant [email protected]@
{
}

References

  • Sutter Guru of the Week (GOTW) – 91
  • HIC++ v3.3 – 11.4
  • HIC++ v3.3 – 11.5

View references >

8.2.4 Do not pass std::unique_ptr by const reference

An object of type std::unique_ptr should be passed as a non-const reference, or by value. Passing by non-const reference signifies that the parameter is an in/out parameter. Passing by value signifies that the parameter is a sink (i.e. takes ownership and does not return it). A const reference std::unique_ptr parameter provides no benefits and restricts the potential callers of the function.

#include <cstdint>            
#include <memory>
             
void foo (std::unique_ptr & p_in_out);            // @@+ Compliant [email protected]@
void foo (std::unique_ptr p_sink);                // @@+ Compliant [email protected]@
void foo (std::unique_ptr const & p_impl_detail); // @@- Non-Compliant [email protected]@


References

  • Sutter Guru of the Week (GOTW) – 91

View references >

8.3 Function Definitions


8.3.1 Do not write functions with an excessive McCabe Cyclomatic Complexity

The McCabe Cyclomatic Complexity is calculated as the number of decision branches within a function plus 1. Complex functions are hard to maintain and test effectively. It is recommended that the value of this metric does not exceed 10.

#include <cstdint>
               
void foo (int32_t a, bool b, bool c)
{
if (a > 0)                            // 1
{
if (b)                                // 2
{
}
   
for (int32_t i (0); i < a; ++i)       // 3
{
}
   
if (c)                                // 4
{
}
}
else if (0 == a)                        // 5
{
if (b)                                // 6
{
}
   
if (c)                                // 7
{
}
}
else
{
if (c)                                // 8
{
}
   
for (int32_t i (-a - 1); i >= 0; --i) // 9
{
}
   
if (b)                                // 10
{
}
}
// @@- Non-Compliant: STCYC = #decisions + 1 = 11 [email protected]@
}

References

  • HIC++ v3.3 – 4.1

View references >

8.3.2 Do not write functions with a high static program path count

Static program path count is the number of non-cyclic execution paths in a function. Functions with a high number of paths through them are difficult to test, maintain and comprehend. The static program path count of a function should not exceed 200.

bool foo ();
               
void bar ()
{
if (foo ()) // 2 paths
{
}
if (foo ()) // 4 paths
{
}
if (foo ()) // 8 paths
{
}
if (foo ()) // 16 paths
{
}
if (foo ()) // 32 paths
{
}
if (foo ()) // 64 paths
{
}
if (foo ()) // 128 paths
{
}
if (foo ()) // @@- Non-Compliant: 256 paths [email protected]@
{
}
}

References

  • HIC++ v3.3 – 4.2

View references >

8.3.3 Do not use default arguments

Use of default arguments can make code maintenance and refactoring more difficult. Overloaded forwarding functions can be used instead without having to change existing function calls.

#include <cstdint>
   
void foo (int32_t i, int32_t j = 0); // @@- Non-Compliant [email protected]@
               
// @@+ Compliant [email protected]@
void bar (int32_t i, int32_t j);
inline void bar (int32_t i)
{
bar (i, 0);
}

References

  • Make default arguments the same or absent when overriding a virtual function – 9.1.2

 

8.4 Initializers


8.4.1 Do not access an invalid object or an object with indeterminate value

A significant component of program correctness is that the program behavior should be deterministic. That is, given the same input and conditions the program will produce the same set of results. If a program does not have deterministic behavior, then this may indicate that the source code is reliant on unspecified or undefined behavior. Such behaviors may arise from use of:

  • Variables not yet initialized.
  • Memory (or pointers to memory) that has been freed.
  • Moved from objects.
#include <cstdint>
#include <iostream>
   
class A
{
public:
A();
// ...
};
                 
std::ostream operator<<(std::ostream &, A const &);
   
int main ()
{
int32_t i;
A a;
                   
std::cout << i << std::endl; // @@- Non-Compliant: 'i' has indeterminate value [email protected]@
std::cout << a << std::endl; // @@+ Compliant: Initialized by constructor call [email protected]@
}

Note: For the purposes of this rule, after the call to std::move has been evaluated the moved from argument is considered to have an indeterminate value.

#include <cstdint>
#include <vector>
                 
int main ()
{
std::vector<int32_t> v1;
std::vector<int32_t> v2;
     
std::vector<int32_t> v3 (std::move (v1));
std::vector<int32_t> v4 (std::move (v2));
     
v1.empty (); // @@- Non-Compliant: 'v1' considered to have indeterminate value [email protected]@
     
v2 = v4;     // @@+ Compliant: New value assigned to 'v2' [email protected]@
v2.empty (); // @@+            before it is accessed    ' [email protected]@
}


References

  • Postpone variable definitions as long as possible - 6.4.1
  • HIC++ v3.3 - 8.4.3
  • C++11 - 8.5/11

View references >

8.4.2 Ensure that a braced aggregate initializer matches the layout of the aggregate object

If an array or a struct is non-zero initialized, initializers should be provided for all members, with an initializer list for each aggregate (sub)object enclosed in braces. This will make it clear what value each member is initialized with.

#include <cstdint>
   
struct S
{
int32_t i;
int32_t j;
int32_t k;
};
               
struct T
{
struct S s;
int32_t a[5];
};
               
void foo ()
{
S s1 = {0, 1};    // @@- Non-Compliant: one member is not explicitly initialized [email protected]@
S s2 = {0, 1, 2}; // @@+ Compliant [email protected]@
                 
T t1 = {0, 1, 2, 3, 4, 5, 6, 7};     // @@- Non-Compliant [email protected]@
T t2 = {0, 1, 2, {3, 4, 5, 6, 7}};   // @@- Non-Compliant [email protected]@
T t3 = {{0, 1, 2}, {3, 4, 5, 6, 7}}; // @@+ Compliant [email protected]@
}

References

  • JSF AV C++ Rev C – 144
  • MISRA C++:2008 – 8-5-2

View references >

Request PDF Version

 

 

Book traversal links for 8. Definitions

  • ‹ 7. Declarations
  • High Integrity C++ Coding Standard
  • 9. Classes ›

Footer menu

  • Products
    • Plan
    • Helix ALM
    • Hansoft
    • Create & Develop
    • Helix Core
    • Helix4Git
    • Helix DAM
    • Helix TeamHub
    • Helix Swarm
    • Methodics IPLM
    • VersIC
    • Test & Validate
    • Helix QAC
    • Klocwork
    • Operate, Manage, & Scale
    • SourcePro
    • HostAccess
    • HydraExpress
    • PV-WAVE
    • Stingray
    • Visualization
  • Solutions
    • By need
    • Application Lifecycle Management
    • Agile Project Management
    • DevOps
    • Version Control
    • IP Lifecycle Management
    • Static Analysis
    • Audit & Compliance
    • Backlog Management
    • Project Portfolio Management
    • By industry
    • Aerospace & Defense
    • Automotive
    • Embedded Systems
    • Semiconductor
    • Energy & Utilities
    • Finance
    • Game Development
    • Virtual Production
    • Government
    • Life Sciences
    • Software
  • Services
    • Consulting/Professional Services
    • Consulting Services Overview
    • Akana
    • BlazeMeter
    • Helix ALM
    • Helix Core
    • Helix QAC
    • Klocwork
    • Methodics IPLM
    • OpenLogic
    • Perfecto
    • Zend
    • Training
    • Training Overview
    • Hansoft
    • Helix ALM
    • Helix Core
    • Helix QAC
    • Klocwork
    • OpenLogic
    • Perfecto
    • Zend
  • Resources
    • Papers & Videos
    • Events & Webinars
    • Recorded Webinars
    • Blog
    • Perforce U
  • Support
  • Customers
    • Case Studies
  • About
    • Our Team
    • Our Culture
    • Careers
    • Press
    • Contact Us
  • Partners
    • Integrations
    • Resellers
  • Quick links
    • Free Trials
    • Subscription Center
    • Customer Support Login
    • Educational Licenses
    • How to Buy
Home
Perforce

Copyright © Perforce Software, Inc. All rights reserved.  |  Sitemap  |  Terms of Use  |  Privacy Policy

Social menu

  • Facebook
  • Twitter
  • LinkedIn
  • YouTube
  • RSS
Send Feedback