C++ Core Guidelines: Lifetime Safety

C++ Core Guidelines: Lifetime Safety

This is a cross-post from www.ModernesCpp.com.

The lifetime safety profile in the C++ core guidelines boils down to one issue: don't dereference a possible invalid pointer. A pointer may be invalid because it is not initialised or the nullptr. A pointer may also point beyond its rage or to a deleted object.

Lifetime Safety

When you don't dereference a possible invalid pointer, the impact to your program is according to the C++ core guidelines manifold:

  • eliminates one of the major sources of nasty errors in C++
  • eliminates a major source of potential security violations
  • improves performance by eliminating redundant “paranoia” checks
  • increases confidence in correctness of code
  • avoids undefined behavior by enforcing a key C++ language rule

Honestly, dealing with pointers is part of a bigger story: ownership. Ownership means that at each point in time, it must be obvious, who is responsible for managing the lifetime of an object. Roughly speaking, C++11 support six kinds of ownership:

  • Local objects. The C++ runtime, as the owner automatically manages the lifetime of these resources. The same holds for global objects or members of a class. The guidelines calls them scoped objects.
  • References: I'm not the owner. I only borrowed the resource that cannot be empty.
  • Raw pointers: I'm not the owner. I only borrowed the resource that can be can be empty. I must not delete the resource.
  • std::unique_ptr: I'm the exclusive owner of the resource. I may explicitly release the resource.
  • std::shared_ptr: I share the resource with other shared pointer. I may explicitly release my shared ownership.
  • std::weak_ptr: I'm not the owner of the resource, but I may become temporary the shared owner of the resource by using the method std::weak_ptr::lock.

Compare this fine-grained ownership semantic with a raw pointer. Now you know, what I like about modern C++.

Now, you may ask yourself: Having rules is fine but how can I check that my code follows these rules? Thanks to the Guidelines Support Library (GSL) the rules of the C++ core guidelines can automatically be checked. 

Checking the Rules of the Guidelines

The GSL is a small library for supporting the guidelines of the C++ core guidelines. They are already a few implementations of the GSL available.

The GSL is a header only library, hence, you can use the functions and types of the library quite easily. The best-known implementation is the one from Microsoft, hosted at Github: Microsoft/GSL. The Microsoft version requires C++14 support and runs on various platforms. Here are a few quite popular platforms:

  • Windows using Visual Studio 2015
  • Windows using Visual Studio 2017
  • Windows using Visual Studio 2019
  • Windows using Clang/LLVM 3.6
  • Windows using Clang/LLVM 7.0.0
  • Windows using GCC 5.1
  • Windows using Intel C++ Compiler 18.0
  • GNU/Linux using Clang/LLVM 3.6-3.9
  • GNU/Linux using Clang/LLVM 4.0
  • GNU/Linux using Clang/LLVM 5.0
  • GNU/Linux using Clang/LLVM 6.0
  • GNU/Linux using Clang/LLVM 7.0
  • GNU/Linux using GCC 5.1

Let's see what I can achieve with the GSL. Here is a program, which breaks Type Safety, Bounds Safey, and Lifetime Safety.

Break of Type Safety, Bounds Safety, and Lifetime Safety

// gslCheck.cpp

#include <iostream>

void f(int* p, int count) {
}

void f2(int* p) {
    int x = *p;
}

int main() {

    // Break of type safety
    // use of a c-cast
    double d = 2;
    auto p = (long*)&d;
    auto q = (long long*)&d;

    // Break of bounds safety
    // array to pointer decay
    int myArray[100];
    f(myArray, 100);

    // Break of Lifetime Safety
    // a is not valid
    int* a = new int;
    delete a;
    f2(a);

}

The comments in the source code document my issues. Now, let me start Visual Studio 2019 and show my steps to visualise the issues.

Enable Code Analysis on Build

No alt text provided for this image

You have to enable the Checkbox. Per default, the three Type Safety, Bounds Safety, and Lifetime Safety rules are not part of the Microsoft Native Recommended Rules.

Configure your Active Rules

As you can see from the screenshot, I create my ruleset CheckProfile, which consisted of the rules C++ Core Guidelines Bounds Rules, C++ Core Guidelines Type Rules, and C++ Core Guidelines Lifetime Rules.

No alt text provided for this image

Run Code Analysis on Solution

Applying my set of rules on the code example was quite promising.

No alt text provided for this image

All issues are found. For each issue such as the first one, I get the line number (17), and the rule of the affected profile (type.4).

Suppress Warnings

Sometimes, you want to suppress specific warnings. You can achieve this with attributes. My next example applies two times an array to pointer decay. Only the second call should give a warning.

// gslCheckSuppress.cpp

#include <iostream>

void f(int* p, int count) {
}

int main() {

    int myArray[100];
    
    // Break of bounds safety
    [[gsl::suppress(bounds.3)]] {   // suppress warning
        f(myArray, 100);
    }

    f(myArray, 100);                // warning           

}

The attribute gsl::suppress(bounds.3) behaves as expected. It's only valid in its scope. The second break of bounds safety is displayed.

No alt text provided for this image

What's next?

I skip the next section of the C++ core guidelines because I already wrote a post to the Guidelines Support Library. I assume the next chapter will be quite controversial: naming and layout rules.

 

Layton Perrin

Entrepreneur, Leader, Architect, Full-Stack Extreme Virtuoso: Business Analysis, Cyber Security, Data Science. ITIL BPM SLM Expert bringing Modern Approaches to drive Business Processes.

5 å¹´

Aha - simplified entity lifecycle management - thank you Rainer :)

赞
回复

要查看或添加评论,请登录

Rainer Grimm的更多文章

  • A Lock-Free Stack: A Hazard Pointer Implementation

    A Lock-Free Stack: A Hazard Pointer Implementation

    Hazard Pointers solve all issues of the previous implementation: A Lock-Free Stack: A Simple Garbage Collector. From…

  • A Lock-Free Stack: A Simple Garbage Collector

    A Lock-Free Stack: A Simple Garbage Collector

    My next lock-free stack includes a simple garbage collector. I discussed the concurrent execution of more than one…

  • A Lock-Free Stack: Atomic Smart Pointer

    A Lock-Free Stack: Atomic Smart Pointer

    The easiest way to solve this memory leak issue from the last post is to use a std::shared_ptr. Atomic Smart Pointer…

  • A Lock-Free Stack: A Complete Implementation

    A Lock-Free Stack: A Complete Implementation

    My last lock-free stack implementation was incomplete. It only supported push operations.

    2 条评论
  • My ALS Journey (20/n): Aids

    My ALS Journey (20/n): Aids

    Today, I would like to introduce all the important aids that allow me and Beatrix to get through the day My ALS…

    2 条评论
  • My Next Mentoring Program: “Generic Programming (Templates) with C++” starts

    My Next Mentoring Program: “Generic Programming (Templates) with C++” starts

    My next mentoring program, “Generic Programming (Templates) with C++,” starts on February 28th. Registration is open.

  • A Lock-Free Stack: A Simplified Implementation

    A Lock-Free Stack: A Simplified Implementation

    Today, I continue my mini story about lock-free data structures. General Considerations From the outside, the caller’s…

    1 条评论
  • Deferred Reclamation in C++26: Read-Copy Update and Hazard Pointers

    Deferred Reclamation in C++26: Read-Copy Update and Hazard Pointers

    A common problem in concurrency is the so-called ABA problem. That means you read a variable twice, which returns the…

  • std::format Extension

    std::format Extension

    Displaying the address of an arbitrary pointer in C++ 20 fails but succeeds with C++26. C++20 Only void, const void…

  • C++26 Library: string and string_view Processing

    C++26 Library: string and string_view Processing

    C++26 offers many small improvements around strings and string_views. First of all: What is a std::string_view A is a…

    1 条评论

社区洞察

其他会员也浏览了