March 2024

C++ and The Next 30 Years -- David Sankel

sankel-next30years.pngI delivered a keynote, C++ and the Next 30 Years, at the 2024 CPP-Summit conference in Beijing, China. Experiencing the culture, the people, and the landscape was tremendous. In this post I’ll cover some of the points in my future-looking C++ talk and share my experience giving a talk for the first time in China.

C++ and The Next 30 Years

by David Sankel

From the article:

My talk: C++ and the Next 30 Years

The title of my keynote was C++ and the Next 30 Years which covered C++’s evolution, the changing landscape of programming languages, and the influence of AI. Here I break down some of my talk’s key points.

The next 10 years

In the next 10 years I expect C++ modules to become more accessible. Most C++ vendors have at least some support and CMake recently announced its feature set. However, transitioning existing code bases and, in many instances, bespoke build systems will be a great obstacle.

Package manager usage is on the rise, but the growth curve is slow. I don’t expect any tool to capture more than 40% market share by the decade’s end.

 

Is shadowing a member variable from a base class a bad thing? Maybe, but maybe not. -- Raymond Chen

RaymondChen_5in-150x150.jpgIn C++, shadowing occurs when a name in one scope hides an identical name in another scope, sparking debate over its merit. This article explores scenarios where shadowing can either protect code integrity or hinder its evolution, highlighting its dual nature and impact on code maintenance. Join Raymond as he unravels the complexities of shadowing in C++, revealing its intricate balance between benefit and drawback.

Is shadowing a member variable from a base class a bad thing? Maybe, but maybe not.

by Raymond Chen

From the article:

What is shadowing? In C++, shadowing is the name given to the phenomenon when a name in one scope hides an identical name in another scope.

Is shadowing bad? That’s a harder question.

Whether shadowing is good or bad depends on the order in which the conflicting names were introduced.

Suppose you have a class library, and one of the classes is this:

struct Tool {
    int a;
};

And suppose some customer uses your class like this:

class Wrench : public Tool {
private:
    int a;
};

In this case, shadowing is probably unintended. The customer has accidentally shadowed Tool::a, and any references to a in the Wrench class will refer to Wrench::a, even if the author meant to access Tool::a.

Meanwhile, you have another customer who writes this...

Providing a stable memory address to an external API

A post on how to provide a pointer to a Qt Model/View or other APIs storing pointers to their data without using shared_ptr or unique_ptr for the actual object.

Providing a stable memory address

by Jens Weller

From the article:

Some APIs allow you to store a pointer to your data element. This is used to access additional information from your types to display them in Model/View Architecture.

A while ago I showed how you can implement a tree with shared_ptr and enable_shared_from_this and then display this in QTreeView. And when working on my current project I knew this problem would come around again. Maybe not for a tree and a tree view, but I'll clearly need to have some way to have ui panels display and edit my data classes and store a stable memory adress as a pointer in Qt models. Back in 2015 the Qt5 example still used a pointer allocated with raw new for this, in Qt6 the example uses unique_ptr. Using shared_ptr for this back in 2015 was a good decision, and the code works very well. For the moment I don't see that my current project would need to make use of enable_shared_from_this, so using unique_ptr would be a good option...

 

 

C++23: More Small Changes -- Sandor Dargo

SANDOR_DARGO_ROUND.JPGIn this post, we continue discovering the changes introduced by C++23. We are going to look into three (and a half) small changes, each affecting constructors of some standard library types. We’re going to see how new constructors for container types, a new range constructor for string_view and some default template arguments for pair.

C++23: More Small Changes

by Sandor Dargo

From the article:

As of C++20, almost all container-like objects (containers and container-adaptors) can be initialized with a pair of iterators.
std::vector<int> v{42, 51, 66};
std::list<int> l(v.begin(), v.end());
All of them, except for std::stack and std::queue. They don’t provide such overloads. If you want to initialize them with a pair of iterators, you need an intermediary std::initiailizer_list.
std::vector<int> v{42, 51, 66};
// std::queue<int> q1(v.begin(), v.end()); // DOESN'T COMPILE!
std::queue<int> q2({v.begin(), v.end()});

This inconsistency, at first, looks like a small inconvenience. But its effects are much deeper. While using the stack or queue on its own is not a big burden, if you want to offer functionality that works with all container-like objects, you have a higher price to pay.

Due to the lack of an iterator-pair-based constructor, you either have to ...

Safety, Revisited -- Lucian Radu Teodorescu

logo.pngLast year saw a proliferation of talks and articles about safety in C++. Lucian Radu Teodorescu gives an overview of these and presents a unified perspective on safety.

Safety, Revisited

by Lucian Radu Teodorescu

From the article:

In his presentation at C++ now [Parent23a], Sean Parent presents the reasons why it’s important to discuss safety in the C++ world, tries to define safety, argues that the C++ model needs to improve to achieve safety, and looks at a possible future of software development. This same talk was later delivered as a keynote at C++ on Sea [Parent23b].

Sean argues the importance of safety by surveying a few recent US and EU reports which have begun to recognise safety as a major concern [NSA22CR23WH23aEC22]. There are a few takeaways from these reports. Firstly, they identify memory safety as a paramount issue. The NSA report [NSA22], for instance, cites a Microsoft study noting that “70 percent of their vulnerabilities were due to memory safety issues”. Secondly, they highlight the inherent safety risks in C and C++ languages, advocating for the adoption of memory-safe languages. Lastly, these documents suggest a paradigm shift in liability towards software vendors. Under this framework, vendors may face accountability for damages resulting from safety lapses in their software.

Building on the reports that underscore the significance of safety, Sean delves into deciphering the meaning of ‘safety’ in the context of software development. After evaluating several inadequate definitions, he adopts a framework conceptualised by Leslie Lamport [Lamport77]. The idea is to express ...

 

Starting a C++ project with CMake in 2024

A post on how I've recently started a new C++ project.

Starting a C++ project with CMake in 2024

by Jens Weller

From the article:

Last year I've written last year about my plans to return to C++, taking on some project ideas with C++20 and CMake.

The first project is now in its beginning, so I thought to share the steps so far. Some of this blog post is covered by my recent talk Starting a modern C++ project with CMake in 2024. In this post I'm going stay within the parts of the build tooling, following up with the code in other posts.

After working through the official CMake tutorial...

 

C++23: Allocator Related Changes -- Sandor Dargo

SANDOR_DARGO_ROUND.JPGIn this post, we are going to review two changes related to allocators in C++. One is about providing size information about the allocated memory and the other is about how CTAD should happen for containers with non-default allocators.

C++23: Allocator Related Changes

by Sandor Dargo

From the article:

P0401R6 gives a new way to allocate memory on the heap to limit spurious reallocations.

The new interface of std::allocator looks like this, but there is also a free function version of it.

template<class Pointer>
  struct allocation_result {
    Pointer ptr;
    size_t count;
  };

// this class already exist:
namespace std {
  template<class T> class allocator {
   public:
   // lots of existing things
   // ...
   // this is the old way to allocate 
   [[nodiscard]] constexpr T* allocate(size_t n);

   // and this is the new way
   [[nodiscard]] constexpr allocation_result<T*> allocate_at_least(size_t n);

   // the interface for deallocation does not change
   constexpr void deallocate(T* p, size_t n);
  };
}
As you can see, allocate_at_least takes a number and it should allocate enough memory for at least that many instances of T on the heap. While allocate returns a single pointer to the beginning of the allocated memory, allocate_at_least returns a new struct called allocation_result which has two members, the “usual” pointer to the beginning of the allocated memory (ptr) and the number of Ts memory got allocated for (count). count must be at least as large as the input parameter n, but it can also be more.