Articles & Books

C++20, Spans, Threads and Fun -- Bartlomiej Filipek

C++20_Spans_Threads_and_Fun.pngIn this post, we’ll have fun using C++20’s spans to process data on multiple threads. What’s more, we’ll be equipped with the latest concurrency features from C++20.

C++20, Spans, Threads and Fun

by Bartlomiej Filipek

From the article:

Our task is relatively simple but can be extended to various multi-phase computations.

We need to initialize a container with numbers, filter them, then build a histogram.

Here’s the overview of the process:

CLion Nova Explodes onto the C and C++ Development Scene -- Anastasia Kazakova

clionnova.pngWe’re announcing a free early preview of CLion, which uses the ReSharper C++/Rider C++ language engine instead of the CLion "legacy" engine. The Preview build is available via our dedicated Toolbox App feed. At some point in 2024, depending on the results of the feedback collected, CLion Nova will be merged into CLion. Until then, the Preview build will be free to use and can be installed in parallel with your usual CLion (Classic) installation.

CLion Nova Explodes onto the C and C++ Development Scene

by Anastasia Kazakova

From the article:

The first C++ engine by JetBrains was designed for AppCode, our IDE for iOS and macOS developers. It was part of the IntelliJ Platform, initially written in Java and later also in Kotlin. The approach and the architecture of the engine serve many languages in IntelliJ-based IDEs well; however, this design turned out not to be the best fit for the C++ language specifically.

To more quickly align with the evolution of C++ and to separate the engine and IDE processes, a clangd-based engine was later added to CLion. Built on our custom branch of clangd, this engine detects any warnings and errors, shows them in the editor, and suggests quick-fixes, as well as performing highlighting, completion, and certain navigation actions. It’s also used for things like data flow analysis and MISRA checks. Meanwhile, CLion’s “legacy” engine is responsible for other code insight features like refactorings. You can see a detailed “list of responsibilities” in our CLion documentation.

How Can I Prevent Myself From Using a Parameter After I’ve Extracted All Value? -- Raymond Chen

Imagine you have a function parameter that you want to protect from direct access, ensuring that all future interactions occur through a wrapper or transformation. This situation often arises in scenarios like implementing a logging wrapper for a class. In this discussion, we'll explore a clever technique known as "hide_name" to achieve this goal, allowing you to enforce the use of the wrapper and prevent direct access to the parameter.

How Can I Prevent Myself From Using a Parameter After I’ve Extracted All Value From It?

By Raymond Chen

From the article:

Suppose you have a function that takes a parameter that you want to transform in some way, and you want to require that all future access to the parameter be done through the transformed version. One example is a wrapper class that does logging.¹

struct WidgetRefWrapper
{
    WidgetRefWrapper(
        Widget& widget,
        Logger& logger) :
    m_widget(widget), m_logger(logger) {}
    
    void Toggle() try
    {
        m_logger.Log("Toggling the widget");
        m_widget.Toggle();
        m_logger.Log("Toggled the widget");
    } catch (...) {
        m_logger.Log("Exception while toggling the widget");
        throw;
    }

private:
    Widget& m_widget;
    Logger& m_logger;
};

void DoSomething(Widget& widget)
{
    Logger& logger = GetCurrentLogger();
    WidgetWrapper wrapper(widget, logger);

    // Do not use the widget directly!
    // Always use the wrapper!

    if (needs_toggling) {
        wrapper.Toggle();
    }
}

You want that “Do not use the widget directly!” comment to have some teeth. Can you “poison” the widget parameter so it cannot be used any more?

Striving For Better C++ Code, Part I: Data Flow Analysis Basics -- Anastasia Kazakova

Anastasia-200x200.jpgWe’ll look at the basics of data flow analysis, including how it works in general, while presenting several real-world examples where it can help you write better code.

Striving For Better C++ Code, Part I: Data Flow Analysis Basics

by Anastasia Kazakova

From the article:

All data flow inspections rely on the control-flow graph. This is a graph on which vertices are the statements in the program and edges are the control flow jumps between these statements (direct code execution, conditional jumps, loops, breaks, gotos, etc.).

For example, the control-flow graph at the right represents the function foo on the left:

basic_sample_scheme.png

How to use std::span from C++20 -- Bartlomiej Filipek

How_to_use_std_span_from_C++20.pngIn this article, we’ll look at std::span which is more generic than string_view and can help work with arbitrary contiguous collections.

How to use std::span from C++20

by Bartlomiej Filipek

From the article:

Here’s an example that illustrates the primary use case for std::span:

In traditional C (or low-level C++), you’d pass an array to a function using a pointer and a size like this:

void process_array(int* arr, std::size_t size) {
  for(std::size_t i = 0; i < size; ++i) {
    // do something with arr[i]
  }
}

std::span simplifies the above code:

void process_array(std::span<int> arr_span) {
  for(auto& elem : arr_span) {  
    // do something with elem  
  } 
} 

The need to pass a separate size variable is eliminated, making your code less error-prone and more expressive.

Enodo, Divide et Impera -- Lucian Radu Teodorescu

Enodo,_Divide_et_Impera.pngHow do you untie the knotty problem of complexity? Lucian Radu Teodorescu shows us how to divide and conquer difficult problems.

Enodo, Divide et Impera

By Lucian Radu Teodorescu

From the article:

This article aims to analyse one of the most useful techniques in software engineering: the divide et impera (Divide and Conquer) technique. And maybe the most useful one.

We define the divide et impera method as a way of breaking up a problem into smaller parts and fixing those smaller parts. This applies to recursive functions (where the phrase divide et impera is most often used), but it will also apply to the decomposition of problems. At some point, we will also discuss using abstraction as a way of applying divide et impera. Finally, we will show how to use this technique in our daily engineering activities that are not strictly related to coding.

In this article, we call divide et impera a method of approaching problems that has the following characteristics:

  • breaking the problem into sub-problems
  • solving the sub-problems independently of each other
    • occasionally, an answer to a sub-problem may render solving the rest of the sub-problems unnecessary
    • sporadically, a small amount of information passes one sub-problem to another
  • combining the results of the sub-problem solutions to form the solution to the initial problem