intermediate

C++ Static Analysis using Clang -- Ehsan Akhgari

How to write/use C++ static analyzer using Clang.

C++ Static Analysis using Clang

by Ehsan Akhgari

From the article:

Large code bases typically develop rules around how various code constructs should be used.  These rules help eliminate bugs resulting from common mistakes.  C++ gives programmers a good amount of power over enforcing such rules using the facilities that the language provides.  As a simple example, if you have a class that should not be inherited from, you can mark the class as final.

Typically one finds themselves in a situation where the language doesn’t provide an easy way to enforcey something.  In that case, the solution is typically enforcing the rules through documentation, code review, etc.  Besides the obvious downside of people making mistakes when checking for these rules, detecting violations of the some rules may be completely impractical.

C++ Core Guidelines Checkers available for VS 2015 Update 1--Andrew Pardoe and Neil MacIntosh

Coding well in C++ is becoming easier:

C++ Core Guidelines Checkers available for VS 2015 Update 1

by Andrew Pardoe and Neil MacIntosh

From the article:

Back in September at CppCon 2015 Neil announced that we would be shipping new code analysis tools for C++ that would enforce some of the rules in the C++ Core Guidelines. (A video of the talk is available here: https://www.youtube.com/watch?v=rKlHvAw1z50 and slides are available on the ISOCpp GitHub repo.)

Quick Q: C++ regex: Conditional replace

Quick A: Use regex_token_iterator

Recently on SO:

C++ regex: Conditional replace

Use regex_token_iterator


#include <regex>
#include <string>
#include <sstream>
#include <set>
#include <map>

std::string replacer(std::string text) {
    std::string output_text;
    std::set<std::string> keywords = { "foo", "bar" };
    std::map<std::string, int> ids = {};

    int counter = 0;
    auto callback = [&](std::string const& m){
        std::istringstream iss(m);
        std::string n;
        if (iss >> n)
        {
            if (keywords.find(m) != keywords.end()) {
                output_text += m + " ";
            }
            else {
                if (ids.find(m) != ids.end()) {
                    output_text += "ID" + std::to_string(ids[m]) + " ";
                }
                else {
                    // not found
                    ids[m] = counter;
                    output_text += "ID" + std::to_string(counter++) + " ";
                }
            }
        }
        else
        {
            output_text += m;
        }
    };

    std::regex re("\\b\\w*\\b");
    std::sregex_token_iterator
        begin(text.begin(), text.end(), re, { -1, 0 }),
        end;
    std::for_each(begin, end, callback);
    return output_text;
}

 

Quick Q: Why destructor disabling the generation of implicit move functions?

Quick A: Because it means that your class is handling a ressource, thus the compiler cannot know how to move.

Recently on SO:

Why destructor disabling the generation of implicit move functions?

"The Rule of Zero" is in fact about something else than what special member functions are generated and when. It is about a certain attitude to class design. It encourages you to answer a question:

Does my class manage resources?

If so, each resource should be moved to its dedicated class, so that your classes only manage resources (and do nothing else) or only accumulate other classes and/or perform same logical tasks (but do not manage resources).

It is a special case of a more general Single Responsibility Principle.

When you apply it, you will immediately see that for resource-managing classes you will have to define manually move constructor, move assignment and destructor (rarely will you need the copy operations). And for the non-resource classes, you do not need to (and in fact you probably shouldn't) declare any of: move ctor/assignment, copy ctor/assignment, destructor.

Hence the "zero" in the name: when you separate classes to resource-managing and others, in the "others" you need to provide zero special member functions (they will be correctly auto-generated.

There are rules in C++ what definition (of a special member function) inhibits what other definitions, but they only distract you from understanding the core of the Rule of Zero.

For more information, see:

Overload resolution -- Andrzej KrzemieĊ„ski

An introduction to function template specialization, function (template) overloading, argument dependent lookup (ADL) and overload resolution:

Overload resolution

by Andrzej Krzemieński

From the article:

This post is an introduction to another one that I intend to write in the future...

Breaking all the Eggs in C++ -- Scott Meyers

Scott Meyers takes a deeper look into uninitialized memory in his recent blog post.

Breaking all the Eggs in C++

by Scott Meyers

From the article:

If you want to make an omelet, so the saying goes, you have to break a few eggs. Think of the omelet you could make if you broke not just a few eggs, but all of them! Then think of what it'd be like to not just break them, but to replace them with newer, better eggs. That's what this post is about: breaking all the eggs in C++, yet ending up with better eggs than you started with.

NULL, 0, and nullptr

NULL came from C. It interfered with type-safety (it depends on an implicit conversion from void* to typed pointers), so C++ introduced 0 as a better way to express null pointers. That led to problems of its own, because 0 isn't a pointer, it's an int. C++11 introduced nullptr, which embodies the idea of a null pointer better than NULL or 0. Yet NULL and 0-as-a-null-pointer remain valid. Why? If nullptr is better than both of them, why keep the inferior ways around?

Backward-compatibility, that's why. Eliminating NULL and 0-as-a-null-pointer would break exiting programs. In fact, it would probably break every egg in C++'s basket. Nevertheless, I'm suggesting we get rid of NULL and 0-as-a-null-pointer, thus eliminating the confusion and redundancy inherent in having three ways to say the same thing (two of which we discourage people from using).

Cheerp 1.1 - C++ for the Web with fast startup times, dynamic memory and more speed!--Leaning Tech

If you want your C++ code to run on the web, there is Emscripten, but there is also Cheerp:

Cheerp 1.1 - C++ for the Web with fast startup times, dynamic memory and now, more speed!

by Leaning Technologies Ltd.

From the article:

Cheerp is a C++ compiler for the Web platform. Roughly a year ago we released Cheerp 1.0 with the promise of making C++ a first class language for the Web, with full access to DOM and HTML5 APIs (including WebGL) and great performance. At that time, we could only partially meet that promise.

With our early adopters starting to use Cheerp on real world, large scale applications, we were proud to see that Cheerp could indeed be used to seamlessly integrate C++ code into HTML5 apps. But we also realized that the performance of the compiled code was disappointing on real codebases.

As an example, our first benchmarking result on our first large-scale (~1M sloc) customer code was around forty times (40x) slower than native. Not only was this result disappointing, but it also was much worse than what we were expecting based on our internal benchmarks.

One year later, after significant effort focused on performance optimizations, we are here today to announce Cheerp 1.1...