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

3. Basic Concepts

3.1 Scope


3.1.1 Do not hide declarations

Reusing the same identifier for different declarations is confusing and difficult to maintain. If the hiding declaration is later removed or the identifier is renamed, a compilation error may not be generated, as the declaration that was previously hidden will now be found. While hidden namespace scope identifiers can still be accesses with a fully qualified name, hidden block scope identifiers will not be accessible.

#include <cstdint>
               
void foo (int32_t);
               
int32_t i;
               
void bar (int32_t max) 
{
for (int32_t i (0); i < max; ++i)   // @@- Non-Compliant [email protected]@
{
for (int32_t i (0); i < max; ++i) // @@- Non-Compliant [email protected]@
{
// no way to access the outer loop index
foo (::i); // namespace scope 'i'.
foo (i);   // innermost declaration of 'i'
}
}
}

In C++, it is possible for the same identifier to refer to both a type and an object or a function. In this case the object or function will hide the type.

#include <cstdint>
               
// valid C++
class C;
int32_t C;   // @@- Non-Compliant: object C hides type of same name [email protected]@

References

  • HIC++ v3.3 - 8.2.1

View references >

3.2 Program and Linkage


3.2.1 Do not declare functions at block scope

A declaration for a function should be common to its definition, any redeclarations, and any calls to it. To ensure that the same type is used in all declarations, functions should always be declared at namespace scope (See rules <hicpp ref=”dcl.link.single-decl”/> and <hicpp ref=”dcl.link.unnamed-ns-members”/>).

#include <cstdint>
               
int32_t bar ()
{
int32_t foo ();    // @@- Non-Compliant [email protected]@
return foo ();
}
               
int32_t foo ()
{
}

References

  • JSF AV C++ Rev C – 107
  • MISRA C++:2008 – 3-1-2

View references >

3.3 Storage Duration
 

3.3.1 Do not use variables with static storage duration

Variables with linkage (and hence static storage duration), commonly referred to as global variables, can be accessed and modified from anywhere in the translation unit if they have internal linkage, and anywhere in the program if they have external linkage. This can lead to uncontrollable relationships between functions and modules. Additionally, certain aspects of the order of initialization of global variables are unspecified and implementation defined in the C++ language standard. This can lead to unpredictable results for global variables that are initialized at run-time (dynamic initialization). This rule does not prohibit use of a const object with linkage, so long as:

  • it is initialized through static initialization
  • the object is not ODR used
#include <cstdint>
               
static int32_t foo ();
extern int32_t ga (foo ()); // @@- Non-Compliant [email protected]@
extern int32_t gb (ga);     // @@- Non-Compliant [email protected]@
               
namespace 
{
int32_t la (0);           // @@- Non-Compliant [email protected]@
const int32_t SIZE (100); // @@+ Compliant [email protected]@
}

The order of initialization of block scope objects with static storage duration is well defined. However, the lifetime of such an object ends at program termination, which may be incompatible with future uses of the code, e.g. as a shared library. It is preferable to use objects with dynamic storage duration to represent program state, allocated from the heap or a memory pool.

class Application
{
// ...
};
     
Application const & theApp()
{
static Application app; // @@- Non-Compliant [email protected]@
return app;
}

References

  • HIC++ v3.3 – 8.2.2

View references >

3.4 Object Lifetime
 

3.4.1 Do not return a reference or a pointer to an automatic variable defined within the function

The lifetime of a variable with automatic storage duration ends on exiting the enclosing block. If a reference or a pointer to such a variable is returned from a function, the lifetime of the variable will have ended before the caller can access it through the returned handle, resulting in undefined behavior.

class String
{
public: 
String (char *);
String (const String &);
};
     
String & fn1 (char * myArg)
{
String temp (myArg);
return temp;         // @@- Non-Compliant: temp destroyed here [email protected]@
}
     
String fn2 (char * myArg)
{
String temp (myArg);
return temp;         // @@+ Compliant: the caller will get a copy of temp [email protected]@ 
}

References

  • HIC++ v3.3 – 11.7

View references >

3.4.2 Do not assign the address of a variable to a pointer with a greater lifetime

The C++ standard defines four kinds of storage duration:

  • Static
  • Thread
  • Automatic
  • Dynamic

The lifetime of objects with the first three kinds of storage duration is fixed, respectively:

  • Until program termination
  • Until thread termination
  • Upon exiting the enclosing block.

Therefore, undefined behavior will likely occur if an address of a variable with automatic storage duration is assigned to a pointer with static or thread storage duration, or one defined in an outer block. Similarly, for a thread_local variable aliased to a pointer with static storage duration.

#include <cstdint>
               
void foo (bool b)
{
int32_t * p;
if (b)
{
int32_t c = 0;
p = &c;    // @@- Non-Compliant [email protected]@
}
}

If using high_integrity::thread, then references or pointers with local storage duration should not be passed into threads that have the high_integrity::DETACH property.

#include <cstdint>
#include "high_integrity.h"
               
using high_integrity::thread;
using high_integrity::ThreadExec;
   
void bar(int32_t &);
void foo ()
{
int32_t i;
thread <ThreadExec::DETACH> t(bar, std::ref(i)); // @@- Non-Compliant: [email protected]@
                                                 // @@- lifetime of 'i' may end [email protected]@
                                                 // @@- before thread completes [email protected]@
}


References

  • JSF AV C++ Rev C – 173
  • MISRA C++:2008 – 7-5-2

View references >

3.4.3 Use RAII for resources

Objects with non-trivial destructors and automatic storage duration have their destructors called implicitly when they go out of scope. The destructor will be called both for normal control flow and when an exception is thrown. The same principle does not apply for a raw handle to a resource, e.g. a pointer to allocated memory. By using a manager class, the lifetime of the resource can be correctly controlled, specifically by releasing it in the destructor. This idiom is known as Resource Acquisition Is Initialization (RAII) and the C++ language standard provides RAII wrappers for many resources, such as:

  • dynamically allocated memory, e.g. std::unique_ptr
  • files, e.g. std::ifstream
  • mutexes, e.g. std::lock_guard
#include <memory>
#include <cstdint>
                           
void foo_v1 ()
{
int32_t * p = new int32_t; // @@- Non-Compliant [email protected]@
                 
// ... possibly throwing an exception - resource not freed
                 
delete p;
}
               
void foo_v2 ()
{
std::unique_ptr<int32_t> p (new int32_t ());  // @@+ Compliant [email protected]@
                 
// ... possibly throwing an exception - resource freed
                 
}

The following example demonstrates how RAII can also be used to avoid deadlock when an exception is thrown.

#include <list>
#include <mutex>
#include <cstdint>
                           
class ListWrapper
{
public:
void add1(int32_t val)
{
// @@- Non-Compliant:  'unlock' not called if exception thrown by 'push_back' [email protected]@
mut.lock ();
lst.push_back(val); // May throw an exception
mut.unlock ();
}
     
void add2(int32_t val)
{
// @@+ Compliant:  Using lock guarantees unlocking, even where an exception is thrown [email protected]@
std::lock_guard<std::mutex> lock(mut);
lst.push_back(val); // May throw an exception
}
     
// ...
               
private:
std::list<int32_t> lst;
mutable std::mutex mut;
};

Other benefits of using RAII are:

  • Clear documentation of resource ownership.
  • Pre/post conditions when accessing memory.
#include <cstdint>
#include <cassert>
#include <memory>
               
int32_t & f1 ()
{
int32_t * result (new int32_t ());
return *result; // @@- Non-Compliant [email protected]@
}
               
std::unique_ptr<int32_t> f2 ()
{
std::unique_ptr<int32_t> result (new int32_t ());
return result; // @@+ Compliant [email protected]@
}
   
void f3 ()
{
std::weak_ptr<int32_t> p1;
{
std::shared_ptr<int32_t> p2 (std::make_shared<int32_t> (0));
p1 = p2;
} // p2 goes out of scope
   
// can check if pointer is expired
assert ( ! p1.expired () && "Ensure is still valid" );
int32_t i = *p1.lock ();
}

References

  • HIC++ v3.3 – 3.2.5
  • HIC++ v3.3 – 9.5
  • HIC++ v3.3 – 12.5
  • HIC++ v3.3 – 12.8
  • Williams Concurrency – 3.2.1
  • CERT C++ – CON02-CPP

View references >

3.5 Types


3.5.1 Do not make any assumptions about the internal representation of a value or object

Avoid C++ constructs and practices that are likely to make your code non-portable:

  • A union provides a way to alter the type ascribed to a value without changing its representation. This reduces type safety and is usually unnecessary. In general it is possible to create a safe abstraction using polymorphic types.
  • Integer types other than signed / unsigned char have implementation defined size. Do not use integer types directly, instead use size specific typedefs, defined in a common header file, which can then be easily adjusted to match a particular platform.
  • Do not mix bitwise and arithmetic operations on the same variable, as this is likely to be non portable between big and little endian architectures.
  • Do not assume the layout of objects in memory, e.g. by comparing pointers to different objects with the relational operators, using the offsetof macro, or performing pointer arithmetic within an object with unspecified or implementation defined layout.
#include <cstdint>
               
union U             // @@- Non-Compliant [email protected]@
{
float f;
int32_t i;        // @@- Non-Compliant [email protected]@
};
               
uint32_t foo (uint32_t u)
{
--u;
return u & 0xFFU; // @@- Non-Compliant: mixing arithmetic and bitwise operations [email protected]@
}
               
bool cmp (int32_t * lhs, int32_t * rhs)
{
return lhs < rhs; // @@- Non-Compliant [email protected]@
}

References

  • HIC++ v3.3 - 13.6
  • HIC++ v3.3 - 15.1
  • JSF AV C++ Rev C - 210
  • JSF AV C++ Rev C - 210.1
  • JSF AV C++ Rev C - 147
  • JSF AV C++ Rev C - 215
  • MISRA C++:2008 - 3-9-3
  • MISRA C++:2008 - 5-0-15

View references >

Request PDF Version

 

 

Book traversal links for 3. Basic Concepts

  • ‹ 2. Lexical Conventions
  • High Integrity C++ Coding Standard
  • 4. Standard Conversions ›

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