Quantcast
Channel: Bartek's coding blog
Viewing all 325 articles
Browse latest View live

Randomizing lines from a file, a tool in VC++ 2017

$
0
0

Writing a utility tool in VC++ 2017

Is C++ well suited for writing fast small utilities/tools?

Let’s see:

For my recent giveaway I needed a tool that would take an input file - CSV with data and then draw a few winners from all of the entries. To make things more complicated each entry might have a different weight.

Read more for the full description, my solution and experiments.

The Problem

In short:

I have all of the entries to the giveaway (in a file), I need to pick (randomly) 3 winners.

More details:

All of the entries can be exported into CSV. The file has the following structure:

NameEmailEntriesActionsDate
ABCABC@abc.com1052017 May
XYZXYZ@xyz.com112017 June

The field Entries is actually a weight of a user. 1 is the default. If you see weight like 10 it means that the user is 10x likely to win than a user with entries = 1.

How to randomize such structure and pick the winners?

For a start we can load all of the lines (skip the header), then randomize/shuffle the entries and just look at first N (in our case 3) top entries.

The problem is the weight parameter.

In our case, It might be relatively easy as the weight is not a double or float… it’s just an integer value. What we can do is to duplicate the entries as many times as the eight param suggests.

For example:

If there’s a weight of 2 we need to have 2 copies of a given entry.

Then we can shuffle such structure and then users with weights > 1 should have bigger chance to win.

The Solution

I don’t know about you, but I usually didn’t memorize code to load/process a file… but I remembered where could I get some basic parts for my project.

Some time ago there was a post from Meeting C++: Randomizing a CSV File with Standard C++.

Sounds like a good start for me… right?

I didn’t hesitate to take some parts of it and I started my project.

The repo: fenbf/RandomMachine.

As you might expect, it’s not a huge project! I’m not using any super advanced data structures, class hierarchies or complex systems. The tool should work and should be relatively fast to write.

What’s the overall structure?

Let’s have a look at main:

int main(int argc,constchar*argv[])
{
try
{
constauto inputParams =ReadInputParams(argc, argv);

constauto vecLineEntries =ReadAllLines(inputParams);

auto vecIdWithWeights =BuildFromEntries(vecLineEntries);

ShuffleWithMT19937(begin(vecIdWithWeights), end(vecIdWithWeights));

constauto vecWinners =DrawWinners(vecLineEntries,
vecIdWithWeights
,
inputParams
.numElementsToPick);

ShowWinners(vecWinners, vecLineEntries, inputParams);
}
catch(...)
{

}

return0;
}

Core parts:

  • It’s a command line tool, there are several parameters:
    • inputFileName
    • UsersToPick
    • LinesToSkip
    • Column ID of the weight param
    • Column separator
    • I know that I should be using Boost.ProgramOptions, but this time I wrote my own simple parsing.
  • ReadAllLines will open a file and parse it. It produces a vector of all entries. Each entry has a string - with the line text and also a weight param (by default it’s one).
  • Based on entries we build an additional index vector. Here each line entry is expanded/duplicated based on the weight param. But it’s only id, not the full copy.
    • For example if there are two entries, with weights of 2 and 3, we’ll get something like {0, 0, 1, 1, 1 }.
  • The index vector is then shuffled
  • After shuffling we can just look at the top N entries. But we need to take care of drawing only unique winners. Due to the weight it might happen that we pick the same user twice… or more. So if that happens we just look at another entry.
  • After we draw from the collection, we just have to present it.
  • Simplified error handling - using exceptions - is added.
  • I tired to be const correct and used const whenever possible: Please declare your variables as const.

Interesting Parts

In terms of details let’s see how the final function of drawing is built:

vector<LineEntry>
DrawWinners(constvector<LineEntry>& vecInputLines,
constvector<int>& vecWeightedIndices,
unsignedint numElementsToPick)
{
unsignedint winnersFound =0;
std
::set<int> setWinners;
std
::vector<LineEntry> outVec;

for(unsignedint i =0;
winnersFound
< numElementsToPick && i < vecWeightedIndices.size();
++i)
{
constauto index = vecWeightedIndices[i];
constauto&entry = vecInputLines[index];

if(setWinners.find(index)== setWinners.end())
{
setWinners
.insert(index);

outVec
.push_back(entry);

winnersFound
++;
}
}

return outVec;
}

So the above code is responsible for drawing top N entries using randomized index vector. The shuffling part is done before the call to the function. The only little complication is to avoid duplicates of winners. I am using a separate set to mark if a entry is already a winner or not.

Then we just need to output the selected lines.

What are other interesting parts in terms of C++ and Visual Studio?

Modern C++

What’s used from modern C++?

  • auto wherever possible
  • non static data member initialization
  • uniform initialization
  • random: std::random_shuffle is deprecated in C++14 - Meeting C++, and since I got that randomizing code from Meeting C++ it already used mt19937. The only thing I did was to wrap shuffling into a simple template function:
template<typenameItRandom>
voidShuffleWithMT19937(ItRandom itFirst,ItRandom itLast)
{
std
::random_device rd;
std
::mt19937 g(rd());
std
::shuffle(itFirst, itLast, g);
}
  • string_view - have a look at this great post: string_view | Growing up. I was able to use a few string_views across the whole code. But I need to get used to it.
    • So far I’ve noticed that there’s a problem with numeric conversions directly from a string_view. So I needed to make a copy of the string first and then do the conversion (like calling std::atoi).
  • For each loops.
  • move semantics, returning by value, not by output ref/ptr parameter (with also a chance of using Copy Elision).

Visual Studio 2017

With Visual Studio 2017 it’s really easy to write such code. The whole IDE works just better, faster. A lot of tool - even basic refactoring - are there.

For more about VS you can read:

I was happy to see that writing unit tests for native code is as simple as for managed languages. The native unit testing framework makes life so much easier. It just works!

Unit testing native code, Visual Studio 2017

Todo / Experiments

Want to know the best about such pet projects?

You can experiment with it!

How about adding Modules?

In Visual Studio 2017 there’s already early module support. See here Using C++ Modules in Visual Studio 2017 | Visual C++ Team Blog. There’s std.core that brings the Standard Library, so that should work with my sample.

What’s more to add?

I definitely need to add more unit tests, as currently maybe like 50% of code is covered. And not all edge cases are included. Native unit testing framework is really super simple to use.

Soon VC++ 2017.3 will be released (there already preview), and we should get the following big features from C++17:

  • structured bindings
  • guaranteed copy elision
  • constexpr if-statements
  • Selection statements with initializers

For more look here: C++17 Features In Visual Studio 2017 Version 15.3 Preview

It would be great to use structured bindings and selection statements with initializer, just to see how they work in such simple code.

Possibly, if I try hard, I could even came up with an example for constexpr-if.

Any suggestions how to improve my amazing project? :)

Summary

I hope you already know that C++ is also good for writing small utilities.

Maybe such project would be simpler or smaller in Python or C#? I don’t know… but I don’t expect to see a huge difference. I didn’t use explicit memory management, only standard containers, basic exception handling. So the whole app should be quite safe and won’t leak.

Do you write simple tools in C++ or use some different language?

Any suggestions how I could refactor improve the code?

Maybe you have a better solution?


C++17 in details: Attributes

$
0
0

C++17 features, attributes

“C++ Attributes… what?”

There were almost 40% votes like that in my recent Twitter survey. Maybe It would be good to introduce that little-known feature?

There’s even a good occasion, as in C++17 we’ll get even more useful stuff connected with attributes.

Interested?

Intro

Have you ever used __declspec, __attribute or #pragma directives in your code?

For example:

struct S {short f[3];} __attribute__ ((aligned (8)));

void fatal () __attribute__ ((noreturn));

Or for DLL import/export in MSVC:

#if COMPILING_DLL
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT __declspec(dllimport)
#endif

Those are existing forms of compiler specific attributes/annotations.

So what’s an attribute?

An attribute is additional information that can be used by the compiler to produce code. It might be utilized for optimization or some specific code generation (like DLL stuff, OpenMP, etc.).

Contrary to other languages as C#, in C++ that meta information is fixed by the compiler, you cannot add user-defined attributes. In C# you can just ‘derive’ from System.Attribute.

Here’s the deal about C++11 attributes:

With the modern C++, we get more and more standardized attributes that will work with other compilers. So we’re moving a bit from compiler specific annotation to standard forms.

The Series

This post is the fourth in the series about C++17 features details.

The plan for the series

  1. Fixes and deprecation
  2. Language clarification
  3. Templates
  4. Attributes (today)
  5. Simplification (soon)
  6. Library changes 1 (soon + 1)
  7. Library changes 2 (soon + 2)

Just to recall:

First of all, if you want to dig into the standard on your own, you can read the latest draft here:

N4659, 2017-03-21, Working Draft, Standard for Programming Language C++ - the link also appears on the isocpp.org.

Compiler support: C++ compiler support

And you can also grab my list of concise descriptions of all of the C++17 language features:

It’s a one-page reference card, PDF.

There’s also a talk from Bryce Lelbach: C++Now 2017: C++17 Features

And have a look at my master C++17 features post: C++17 Features

OK, let's go back to the main topic of this article...

Before C++11

In short: it was (and still is) a mess :)

#pragma, _declspec, __attribute… a lot of variations and compiler specific keywords.

GCC specific attributes

MSVC specific attributes

Clang specific attributes

The document lists also what syntax is supported, so a lot of those attributes can be already used in modern C++11 form.

Attributes in C++11 and C++14

C++11 did one step to minimize the need to use vendor specific syntax. As I see, the target is to move as much as compiler specific into standardized forms.

The First thing:

With C++11 we got a nicer form of specifying annotations over our code.

The basic syntax is just [[attr]] or [[namespace::attr]].

You can use [[att]] over almost anything: types, functions, enums, etc., etc.

For example:

[[abc]]void foo()
{

}

In C++11 we have the following attributes:

C++14 added:

Note: there no need to use attributes for alignment as there’s alignas separate keyword for that. Before C++11 in GCC you would use __attribute__ ((aligned (N))).

Have a look at also this article Modern C++ Features - Attributes - at Simplify C++.

You know a bit about the old approach, C++11/14… so what the deal about C++17?

C++17 additions

With C++17 we get three more standard attributes

  • [[fallthrough]]
  • [[nodiscard]]
  • [[maybe_unused]]

Plus three supporting features.

[[fallthrough]] attribute

Indicates that a fall-through in a switch statement is intentional and a warning should not be issued for it.

switch(c){
case'a':
f
();// Warning! fallthrough is perhaps a programmer error
case'b':
g
();
[[fallthrough]];// Warning suppressed, fallthrough is ok
case'c':
h
();
}

More details in: P0188R1 and P0068R0 - reasoning.
GCC: 7.0, Clang: 3.9, MSVC: 15.0

[[nodiscard]] attribute

[[nodiscard]] is used to stress that the return value of a function is not to be discarded, on pain of a compiler warning.

[[nodiscard]]int foo();
void bar(){
foo
();// Warning! return value of a
// nodiscard function is discarded
}

This attribute can also be applied to types in order to mark all functions which return that type as [[nodiscard]]:

[[nodiscard]]structDoNotThrowMeAway{};
DoNotThrowMeAway i_promise();
void oops(){
i_promise
();// Warning emitted, return value of a
// nodiscard function is discarded
}

More details:

GCC: 7.0, Clang: 3.9, MSVC: not yet

[[maybe_unused]] attribute

Suppresses compiler warnings about unused entities when they are declared with [[maybe_unused]].

staticvoid impl1(){...}// Compilers may warn about this
[[maybe_unused]]staticvoid impl2(){...}// Warning suppressed


void foo(){
int x =42;// Compilers may warn about this
[[maybe_unused]]int y =42;// Warning suppressed
}

More details:

GCC: 7.0, Clang: 3.9, MSVC: not yet

Attributes for namespaces and enumerators

Permits attributes on enumerators and namespaces.

enum E {
foobar
=0,
foobat
[[deprecated]]= foobar
};

E e
= foobat;// Emits warning

namespace[[deprecated]] old_stuff{
void legacy();
}

old_stuff
::legacy();// Emits warning

More details in:

GCC: 4.9 (namespaces)/ 6 (enums), Clang: 3.4, MSVC: 14.0

Ignore unknown attributes

That's mostly for clarification.

Before C++17 if you tried to use some compiler specific attribute, you might even get an error when compiling in another compiler that doesn’t support it. Now, the compiler simply omits the attribute specification and won’t report anything (or just a warning). This wasn't mentioned in the standard, so needed a clarification.

// compilers which don't 
// support MyCompilerSpecificNamespace will ignore this attribute
[[MyCompilerSpecificNamespace::do_special_thing]]
void foo();

For example in GCC 7.1 there’s a warnings:

warning: 'MyCompilerSpecificNamespace::do_special_thing'
scoped attribute directive ignored [-Wattributes]
void foo();

More details in:

MSVC not yet, GCC: Yes, Clang: 3.9.

Using attribute namespaces without repetition

Other name for this feature was “Using non-standard attributes” in P0028R3 and PDF: P0028R2 (rationale, examples).

Simplifies the case where you want to use multiple attributes, like:

void f(){
[[rpr::kernel, rpr::target(cpu,gpu)]]// repetition
do-task();
}

Proposed change:

void f(){
[[using rpr: kernel, target(cpu,gpu)]]
do-task();
}

That simplification might help when building tools that automatically translate annotated such code into different programming models.

@cppreference.com
Attributes available in C++17

  • [[noreturn]]
  • [[carries_dependency]]
  • [[deprecated]]
  • [[deprecated("msg")]]
  • [[fallthrough]]
  • [[nodiscard]]
  • [[maybe_unused]]

More details in: P0028R4
GCC: 7.0, Clang: 3.9, MSVC: not yet

Summary

I hope that after reading you understood the need of attributes: what are they and when are they useful. Previously each compiler could specify each own syntax and list of available attributes, but in modern C++ the committee tried to standardize this: there are some extracted, common parts. Plus each compiler is not blocked to add it’s own extensions. Maybe at some point, we’ll move away from __attribute or _declspec or `#pragma’?

There’s also quite important quote from Bjarne Stroustrup’s C++11 FAQ/Attributes:

There is a reasonable fear that attributes will be used to create language dialects. The recommendation is to use attributes to only control things that do not affect the meaning of a program but might help detect errors (e.g. [[noreturn]]) or help optimizers (e.g. [[carries_dependency]]).

How about you?

What’s your experience with attributes? Do you use them? Or try to keep your code without the need to do any annotations?

Review: The Complete Software Developer’s Career Guide

$
0
0

The Complete Software Developer’s Career Guide

With around 230 positive reviews (85% of five stars) (4.7 on the average), John Sonmez made a huge success when he published his first book “Soft Skills”. 2.5 years later we get another book. Can the new book continue his success?

Can it move you further with the career?

Bonuses today: giveaway and little Q&A with John.

Let’s see!

The book

The Complete Software Developer’s Career Guide

The Complete Software Developer’s Career Guide

The release date is 19th July, and as I know for a few days there will be a huge discount. Click on the link above for more details.

I probably don’t have to introduce John, as he’s quite a unique person in Software and Personal Development. If you like to know him more, just visit SimpleProgrammer.com

Also, the book was written in parts, and most of that was already published on John’s blog. So you can check it out as well.

The structure

The book consists of five main sections and 60 chapters!

Getting Started as a Software Developer

How to Get Started. The Technical Skills You Need to Have. What Programming Language Should I Learn, College. Coding Boot Camps. Teaching Yourself.

Getting a Job

Internships. Getting a Job Without Experience. How to Find a Job. The Interview Process. Salaries and Negotiation. How to Leave a Job. Switching Mid-Career. Contracting. How the Recruiting Industry Works.

What You Need to Know About Software Development

Overview of Programming Languages. Web Development. Mobile Development. Backend Development. Video Game Development. DBAs and DevOps. Software Development Methodologies. Testing and QA. TDD. Source Control. Continuous Integration. Debugging. Maintaining Code. Types of Work.

Working as a Developer

Dealing with Coworkers and Your Boss. Working With QA. Life / Work Balance. Teams. Selling Your Ideas. How to Dress. The Review Process. Dealing with Prejudice. Being in a Leadership Position. Getting a Raise or Promotion. Women in Tech.

Advancing Your Career

Creating a Reputation. Networking. Keeping Your Skills Up to Date. Generalist vs Specialist. Speaking and Conferences. Creating a Blog. Freelancing and Starting a Business. Career Paths. Job Stability and Security. Training and Certifications. Side Projects.

Best Books to Read. Parting Words

My view

The first thing I liked and struck me was the introduction. I wanted to know if this book is also for an experienced developer. So here are some good parts:

I know. I know you know all this stuff.
You don’t need a basic book from some “hot-shot” on how to get started as a software developer. You don’t need to learn what source control is or get insight on whether you should go to college or boot camp.
I get it—really, I do.

But, trust me on this one, this book is still for you. Here’s why: …

I like the style of writing! After reading a few paragraphs, I can see that John is honest and write about real things, not theoretical stuff. So it’s not just the first few pages that are fun to read. There are much more across the whole book.

I can skip the whole part about the introduction to Software Development, Collage, etc… writing my first resume (since I am already that expert… right? :)). Still, there are areas worth refreshing some of the stuff.

Clearly, I won’t be able to learn a programming language from that book or source control, design pattern… but in those chapters, I could get some basic overview. For example, I am in backed dev mostly… so I liked parts about Web Development.

I focused more on the last two sections: Working as a Developer and Advancing Your Career.

What we have here? Almost everything to move you further in your career and be the best developer in a team.

For example, I totally agree that if you cooperate with your boss, and be:

be the person your boss can count on to resolve problems and move the project forward, and you’ll be regarded as an extremely valuable asset.

Plus, there is also advice how to deal with not perfect bosses, like “Ignoramus”, “Slave Driver,” or micromanagement.

I like that the book strengthens the need to collaborate across all the teams. It’s not just your code, your project. Talk to QA, create better tests, try to get what are the real requirements. Then, by understanding both the bigger picture and the little details, you be able to move further and create better software.

I agree, with the need to build a personal brand. It’s not that you need to create a blog with thousands of readers - that’s one way of course, but you can simply create a strong reputation in your company by being an influential expert in your field or being a great leader. In general, try to create value for others. If you get an exposure/visibility, it will be easier to get a better job or promotion. Not to mention the satisfaction for yourself.

Some bullet point for me to take action:

  • Make my boss happy by using at least daily/weekly reports from my tasks
  • Cooperate with other teams
  • Focus on automation
  • Take responsibility
  • Consistency beats all the other factors regarding blogging
  • Look for other areas, move away from your comfort zone

Summary

Final mark: 4.5/5

Pros:

  • Easy to read as each chapter is a separate part.
  • I like that there are some letters with real dev stories included
  • Practical approach, not much dry theories
  • A lot of content, useful for beginners/intermediate/experts
    • Just pick a topic that is most related to your current career situation.
  • Motivates to do something, be better and move forward.
  • Lots of evergreen content, not only valid for one year… should be valid even in 5 or more years.

Cons:

  • I couldn’t find chapters about remote jobs, would be nice addition
  • Some chapters might feel too general

The book feels like an extension of Soft Skills, but more focused on the programming/career. And it’s also stand-alone, so you don’t have to read Soft Skills first.
It should be a good start for people entering the industry, but also devs who are already inside - to refresh the knowledge, understand other areas of IT, think about other possibilities.
Of course, John sometimes touches the tip of an iceberg, so it’s only a high-level overview (especially in areas like CI, source control, methodologies, etc.) Still, a lot of content is unique - especially for career topics. There are not many books about that.

Have you read the book? What’s your opinion about it?
What’s your favorite book on the similar topic?

Bonus - little Q&A with John

A Few questions to John, with his answers!

Bartek: I’m a C++ programmer, so I need to ask you this :) In the book, you mentioned C++ several times. What do you think about Modern C++? With recent additions to the language in C++11, C++14, and upcoming C++17 it really feels like a new language. Do you still think there’s no future for it? Or the code bases will eventually move to Rust/Java/C#? (or even Java Script :))

John: I like the changes to the language and I think they are very much needed, but I still think the future is somewhat bleak.
What I mean by this is that even though I love C++, the new features and the legacy of it have really added to the complexity and confusion around it.

For example, take some classic book like Effective C++. It’s basically irrelevant at this point.

That’s really confusing. I wish they would have called the new C++ something completely different to break ties with the past.

I also feel like all this has been bolted on.

Of course you could say the same now about C# and Java, which are also beginning to suffer from the same kinds of problems.
In my opinion, C++. C# and Java have all become far too complex as the features have expanded and expanded.

With that said, of course, there is a future for existing C++ developers. There will be C++ for the next 50+ years, I’m sure of it. I just wouldn’t recommend new developers to get into it at this point–unless they really love the language.

Bartek: We have so many online courses, blogs, video… is learning from books still important?
My note: I believe books still have a future as they give a description of a problem from start to finish. If you learn from online/blogs, then the information seems to be more shattered/more chaotic.

John: I agree with you. Books often provide a more thought-out, organized and comprehensive and cohesive view of a topic or subject. Consider how long it takes and how much effort it takes to write a book versus produce a video or blog post.

At the same time though, I do believe video courses are very effective learning tools for software development.

Bartek: Just in five points: what are the 5 key skills of a good software developer?

John:

  1. Able to communicate and organize his ideas clearly.
  2. Ability to self-educate and learn whatever needs to be learned to do the job.
  3. Abstraction. The ability to take and simplify a problem and discover abstractions that further simplify it.
  4. Inspiring and mentoring others. A developer who makes the whole team better is the most valuable asset on a team.
  5. Ability to write clear and readable code. The best developers write code that reads like a book. Because they know that code is read more than written.

What would be your answers to those questions? Do you agree with John?

The giveaway

I’m happy you read through the whole post, so now I have a little prize for you.

I have three copies of John’s new book. Just take part in the giveaway. Enter your details below, add a comment, share my post on Twitter. The whole event lasts for two weeks - until 30th July midnight (Poland Time). I’ll announce winners on Monday 31st July in the morning.

The Complete Software Developer’s Career Guide

C++17 in details: Code Simplification

$
0
0

C++17 features, simplifications

With each C++ standard, we aim for simpler, cleaner and more expressive code. C++17 offers several "big" language features that should make our code nicer. Let’s have a look.

Intro

You might say that most of the new language features (not to mention The Standard Library improvements) are there to write simpler/cleaner code. The “C++17 in details” series reviews most of the bigger things, still for today, I tried to pick a few features that out of the box make your code more compact.

  • Structured bindings/Decomposition declarations
  • Init-statement for if/switch
  • Inline variables
  • constexpr if (again!)
  • a few other mentions

The Series

This post is a fifth in the series about C++17 features details.

The plan for the series

  1. Fixes and deprecation
  2. Language clarification
  3. Templates
  4. Attributes
  5. Simplification (today)
  6. Library changes 1 (soon)
  7. Library changes 2 (soon + 2)
  8. Library changes 3 (soon + 3)
  9. Wrap up, Bonus

Just to recall:

First of all, if you want to dig into the standard on your own, you can read the latest draft here:

N4659, 2017-03-21, Working Draft, Standard for Programming Language C++ - the link also appears on the isocpp.org.

And you can also grab my list of concise descriptions of all of the C++17 language features:

It’s a one-page reference card, PDF.

Links:

OK, let’s discuss the features!

Structured Binding Declarations

Do you often work with tuples?

If not, then you probably should start looking at it. Not only tuples are suggested for returning multiple values from a function, but also they got special language support - so that the code is even easier/cleaner.

For example (got it from std::tie at cppreference):

std::set<S> mySet;

S value
{42,"Test",3.14};
std
::set<S>::iterator iter;
bool inserted;

// unpacks the return val of insert into iter and inserted
std
::tie(iter, inserted)= mySet.insert(value);

if(inserted)
std
::cout <<"Value was inserted\n";

Notice that you need to declare iter and inserted first. Then you can use std::tie to make the magic… Still, it’s a bit of code.

With C++17:

std::set<S> mySet;

S value
{42,"Test",3.14};

auto[iter, inserted]= mySet.insert(value);

One line instead of three! It’s also easier to read and safer, isn’t it?

Also, you can now use const and write const auto [iter, inserted] and be const correct.

Structured Binding is not only limited to tuples, we have three cases:

1. If initializer is an array:

// works with arrays:
double myArray[3]={1.0,2.0,3.0};
auto[a, b, c]= myArray;

2. if initializer supports std::tuple_size<> and provides get<N>() function (the most common case I think):

auto[a, b]= myPair;// binds myPair.first/second

In other words, you can provide support for your classes, assuming you add get<N> interface implementation.

3. if initializer’s type contains only non static, public members:

struct S {int x1 :2;volatiledouble y1;};
S f
();
constauto[ x, y ]= f();

Now it’s also quite easy to get a reference to a tuple member:

auto&[ refA, refB, refC, refD ]= myTuple;

And one of the coolest usage (support to for loops!):

std::map myMap;
for(constauto&[k,v]: myMap)
{
// k - key
// v - value
}

BTW: Structured Bindings or Decomposition Declaration?

For this feature, you might have seen another name “decomposition declaration” in use. As I see this, those two names were considered, but now the standard (the draft) sticks with “Structured Bindings.”

More Details in:

Working in GCC: 7.0, Clang: 4.0, MSVC: VS 2017.3

Init-statement for if/switch

New versions of the if and switch statements for C++:

if (init; condition) and switch (init; condition).

Previously you had to write:

{
auto val =GetValue();
if(condition(val))
// on success
else
// on false...
}

Look, that val has a separate scope, without that it ‘leaks’ to enclosing scope.

Now you can write:

if(auto val =GetValue(); condition(val))
// on success
else
// on false...

val is visible only inside the if and else statements, so it doesn’t ‘leak.’
condition might be any condition, not only if val is true/false.

Why is this useful?

Let’s say you want to search a few things in a string:

const std::string myString ="My Hello World Wow";

constauto it = myString.find("Hello");
if(it != std::string::npos)
std
::cout << it <<" Hello\n"

constauto it2 = myString.find("World");
if(it2 != std::string::npos)
std
::cout << it2 <<" World\n"

We have to use different names for it or enclose it with a separate scope:

{
constauto it = myString.find("Hello");
if(it != std::string::npos)
std
::cout << it <<" Hello\n"
}

{
constauto it = myString.find("World");
if(it != std::string::npos)
std
::cout << it <<" World\n"
}

The new if statement will make that additional scope in one line:

if(constauto it = myString.find("Hello"); it != std::string::npos)
std
::cout << it <<" Hello\n";

if(constauto it = myString.find("World"); it != std::string::npos)
std
::cout << it <<" World\n";

As mentioned before, the variable defined in the if statement is also visible in the else block. So you can write:

if(constauto it = myString.find("World"); it != std::string::npos)
std
::cout << it <<" World\n";
else
std
::cout << it <<" not found!!\n";

Plus, you can use it with structured bindings (following Herb Sutter code):

// better together: structured bindings + if initializer
if(auto[iter, succeeded]= mymap.insert(value); succeeded){
use(iter);// ok
// ...
}// iter and succeeded are destroyed here

More details in

GCC: 7.0, Clang: 3.9, MSVC: VS 2017.3.

Inline variables

With Non-Static Data Member Initialization (see my post about it here), we can now declare and initialize member variables in one place. Still, with static variables (or const static) you usually need to define it in some cpp file.

C++11 and constexpr keyword allow to declare and define static variables in one place, but it’s limited to constexpr’essions only. I’ve even asked a question: c++ - What’s the difference between static constexpr and static inline variables in C++17? - Stack Overflow - to make it a bit clear.

Ok, but what’s the deal with this feature:

Previously only methods/functions could be specified as inline, now you can do the same with variables, inside a header file.

A variable declared inline has the same semantics as a function declared inline: it can be defined, identically, in multiple translation units, must be defined in every translation unit in which it is used, and the behavior of the program is as if there is exactly one variable.

structMyClass
{
staticconstint sValue;
};

inlineintconstMyClass::sValue =777;

Or even:

structMyClass
{
inlinestaticconstint sValue =777;
};

Also, note that constexpr variables are inline implicitly, so there’s no need to use constexpr inline myVar = 10;.

Why can it simplify the code?

For example, a lot of header only libraries can limit the number of hacks (like using inline functions or templates) and just use inline variables.

The advantage over constexpr is that your initialization expression doesn’t have to be constexpr.

More info in:

GCC: 7.0, Clang: 3.9, MSVC: not yet

constexpr if

I’ve already introduced that feature in my previous post about templates: templates/constexpr-if. It was only a brief description, so now we can think about examples that shed some more light on the feature.

Regarding code samples? Hmm… As you might recall constexpr if can be used to replace several tricks that were already done:

  • SFINAE technique to remove not matching function overrides from the overload set
    • you might want to look at places with C++14’s std::enable_if - that should be easily replaced by constexpr if.
  • Tag dispatch

So, in most of the cases, we can now just write a constexpr if statement and that will yield much cleaner code. This is especially important for metaprogramming/template code that is, I think, complex by its nature.

A simple example: Fibonacci:

template<int  N>
constexprint fibonacci(){return fibonacci<N-1>()+ fibonacci<N-2>();}
template<>
constexprint fibonacci<1>(){return1;}
template<>
constexprint fibonacci<0>(){return0;}

Now, it can be written almost in a ‘normal’ (no compile time version):

template<int N>
constexprint fibonacci()
{
ifconstexpr(N>=2)
return fibonacci<N-1>()+ fibonacci<N-2>();
else
return N;
}

In C++ Weekly episode 18 Jason Turner makes an example that shows that constexpr if won’t do any short circuit logic, so the whole expression must compile:

ifconstexpr(std::is_integral<T>::value &&
std
::numeric_limits<T>::min()<10)
{

}

For T that is std::string you’ll get a compile error because numeric_limits are not defined for strings.

In the C++Now 2017: Bryce Lelbach “C++17 Features”/16th minute there’s a nice example, where constexpr if can be used to define get<N> function - that could work for structured bindings.

struct S 
{
int n;
std
::string s;
float d;
};

template<std::size_t I>
auto&get(S& s)
{
ifconstexpr(I ==0)
return s.n;
elseifconstexpr(I ==1)
return s.s;
elseifconstexpr(I ==2)
return s.d;
}

VS previously you would have to write:

template<>auto&get<0>(S &s){return s.n;}
template<>auto&get<1>(S &s){return s.s;}
template<>auto&get<2>(S &s){return s.d;}

As you can see it’s questionable what’s the simpler code here. Although in this case, we’ve used only a simple struct, with some real world examples the final code would be much more complex and thus constexpr if would be cleaner.

More details:

MSVC 2017.3, GCC: 7.0, Clang: 3.9.

Other features

We can argue that most of the new features of C++ simplify the language in one way or the other. In this post, I focused on the bigger parts, also without doing much of repetition.

Still, just for recall you might want to consider the following features, they also make the code simpler:

Not to mention a lot of library features! But we’ll cover them later :)

Summary

In my opinion, C++17 makes real progress towards compact, expressive and easy to read code.

One of the best things is constexpr if that allows to write template/metaprogramming code in a similar way to standard code. For me, it’s a huge benefit (as I am always frightened of those scary template tricks).

The second feature: structured bindings (that works even in for loops) feels like code from dynamic languages (like Python).

As you can see all of the mentioned features are already implemented in GCC and Clang. If you work with the recent versions of those compilers you can immediately experiment with C++17. Soon, a lot of those features will be available in VS: VS 2017.3

  • What are your best C++17 language features that make code cleaner?
  • Have you played with constexpr if or structured bindings?

For now, we’ve covered most of the language features, so now it’s time to move to some new things in the Standard Library. Stay tuned for the next articles in the series!

remember about my C++17 Ref Card:

Blog summary for the first half of 2017

$
0
0

Blog Summary for H! 2017

See my blog stats and thoughts for the first half of the year.

The Story

Keeping things short I’d like to point out a few major things that happened in the first half of 2017:

  • Moved to a weekly schedule!
    • I was usually writing every second week, but then I’ve experimented with a weekly schedule… and it worked out quite nicely! I hope I’ll be able to continue with such pace.
  • Newsletter is growing
    • One year ago I’ve started the list, it was getting like a few people per month. Then with C++17 Ref Card, the number of subscribers skyrocket :) For example, today, I’ve sent the newsletter to 1700+ people!
  • C++17 features
    • It’s 2017, so we need to talk a lot about the new features of C++17. As you see, most of my posts are related to the language changes. Somehow my readers are still not bored with that!
  • C++17 Ref Card - my first product/incentive
    • Just an experiment, but it’s so amazing.
  • Monetization
    • The blog grows, but also the costs. Not to mention the fact that I like the idea of getting some real money out of my writing. So far it’s only a tiny addition, but I am doing various things to increase revenue. Installing ads on the blog might not be the best, and it spoiled the layout… still it’s not hopefully that horrible.
    • I’ve prepared a separate site about possible options to collaborate/advertise - take a look here: Let’s work together.

Actions from my previous summary:

  • Improve the posting pipeline. Keep the quality (or improve it), but reduce the time needed to publish an article.
    • Working on that, but I think the pipeline is better anyway as I write weekly.
  • Keep the plan, don’t take too many breaks :)
    • Done! I moved to the weekly schedule. Only one break at the beginning of June (but newsletter was sent). I think doing a one week break doesn’t hurt, only longer breaks like one… two months. It’s hard to return after such break.
  • Have the buffer of posts
    • Almost :) Working on it
  • Start with some products? Like little self-contained tutorials? Tips and tricks? Bonus content?
    • Not fully done, but I’ve been thinking on that. There’s also C++17 Ref card, which is a tiny/free product.
  • Improve my writing.
    • I didn’t do any particular courses, but I think through practice I do better and better. I use Grammarly, and that makes things a bit easier. I highly recommend Grammarly to anyone who likes to check the writing fast. There’s also a free plan so you can play with it.
  • Write more guest posts

Stats

1st January 2017 till 30th June 2017:

  • Visits: 300,541 (50k monthly) - 148.05% more than the previous six months!
  • Unique visitors: 64,823 (~11k monthly) - 113.30% more than the previous six months!
  • Twitter followers: 1350 (30th June)
  • Mailing list: 1300 (30th June)

C++17 Features

~50k views

C++17 features

This is a bit funny story. Initially, I didn’t plan to write it as it seemed that would be quite a hard topic… describe all the features? Yeah… but then I thought why not use Github/other people and write that in together? Also, it would be impossible to write the complete post in just a day… or even week. So I put my perfectionism aside and just started creating the outline and the framework. And then, once it was live I just needed to fill the holes and keep writing. Plus a few people helped me.

The whole article is still not in the final form, more and more content could be added. But You still seem to like it! Thanks.

C++ 17 in details series

I was motivated by the success of the initial article and realized that it would be best to do some categorization of the features, make more example, improve descriptions. 2017 is also a year of C++17, so the more content about it is the better :)

Posts so far (till end of June)

C++ Status at the end of 2016

~23k views

C++

My sixth update about the language! As always it gives me a positive boost at the beginning of the year!

How To Stay Sane with Modern C++

~15k views

How To Stay Sane With Modern C++

Pseudo Rant/Supportive post about modern C++. While writing code in C++11/14/17 is getting simpler and simpler, it feels like a new language… I still understand the complexity behind. While many samples are much nicer, there are so many new features that people are confused. Especially when you learned old C++, and now everyone tells you to abandon it and be modern.

C++ Jobs and Predictions

-12,5k views

C++ jobs and predictions

The post was motivated by John Sonmez video about a bad situation for C++. I am aware that the language is maybe not as popular as Java or JavaScript. Still, it’s not doomed. I think it’s still a solid asset to know C++. Also, I’ve noticed that the situation on the job market is stable or even growing (as in my city).

Other worth mentioning

C++18 Next Year!

C++18 Next Year

A few people believed that :)

Modern C++ Programming Cookbook Review

Modern C++ Programming

My review of this great book.

Summary

Moving to the weekly schedule, growing the newsletter, writing about C++17. That’s excellent first part of the year!

Thanks for reading the blog!

I tried a lot to bring quality content, especially about the new language standard. With your support, I just plan to continue and write even more about C++ and other good programming stories :)

I haven’t created any survey this time; maybe I’ll do it at the end of the year.

Still, let me know in comments:

  • What topics would you like to see on this blog?
  • What’s your biggest problem with C++?
  • What’s your opinion about this blog?

C++17 in details: Filesystem

$
0
0

C++17 features, simplifications

Although C++ is an old programming language, its Standard Library misses a few basic things. Features that Java or .NET had for years were/are not available in STL. With C++17 there’s a nice improvement: for example, we now have the standard filesystem!

Traversing a path, even recursively is so simple now!

Intro

For the last five episodes/articles, I’ve covered most of the language features. Now it’s time for the Standard Library. I’ve planned three posts on that: Filesystem, Parallel STL and Concurrency, Utils.

Maybe I was a bit harsh in the introduction. Although the Standard Library lacks some important features, you could always use Boost with its thousands of sub-libraries and do the work. The C++ Committee and the Community decided that the Boost libraries are so important that some of the systems were merged into the Standard. For example smart pointers (although improved with the move semantics in C++11), regular expressions, and much more.

The similar story happened with the filesystem. Let’s try to understand what’s inside.

The Series

This post is the sixth in the series about C++17 features details.

The plan for the series

  1. Fixes and deprecation
  2. Language clarification
  3. Templates
  4. Attributes
  5. Simplification
  6. Library changes - Filesystem (today)
  7. Library changes - Parallel STL (soon)
  8. Library changes - Utils (soon + 1)
  9. Wrap up, Bonus

Just to recall:

First of all, if you want to dig into the standard on your own, you can read the latest draft here:

N4659, 2017-03-21, Working Draft, Standard for Programming Language C++ - the link also appears on the isocpp.org.

And you can also grab my list of concise descriptions of all of the C++17 language features:

It’s a one-page reference card, PDF.

Links:

OK, let’s return to our main topic: working with paths and directories!

Filesystem Overview

I think the Committee made a right choice with this feature. The filesystem library is nothing new, as it’s modeled directly over Boost filesystem, which is available since 2003 (with the version 1.30). There are only a little differences, plus some wording changes. Not to mention, all of this is also based on POSIX.

Thanks to this approach it’s easy to port the code. Moreover, there’s a good chance a lot of developers are already familiar with the library. (Hmmm… so why I am not that dev? :))

The library is located in the <filesystem> header. It uses namespace std::filesystem.

The final paper is P0218R0: Adopt the File System TS for C++17 but there are also others like P0317R1: Directory Entry Caching, PDF: P0430R2–File system library on non-POSIX-like operating systems, P0492R2… All in all, you can find the final spec in the C++17 draft: the “filesystem” section, 30.10.

We have three/four core parts:

  • The path object
  • directory_entry
  • Directory iterators
  • Plus many supportive functions
    • getting information about the path
    • files manipulation: copy, move, create, symlinks
    • last write time
    • permissions
    • space/filesize

Compiler/Library support

Depending on the version of your compiler you might need to use std::experimental::filesystem namespace.

Examples

All the examples can be found on my Github: github.com/fenbf/articles/cpp17.

I’ve used Visual Studio 2017 Update 2.

Working with the Path object

The core part of the library is the path object. Just pass it a string of the path, and then you have access to lots of useful functions.

For example, let’s examine a path:

namespace fs = std::experimental::filesystem;

fs
::path pathToShow(/* ... */);
cout
<<"exists() = "<< fs::exists(pathToShow)<<"\n"
<<"root_name() = "<< pathToShow.root_name()<<"\n"
<<"root_path() = "<< pathToShow.root_path()<<"\n"
<<"relative_path() = "<< pathToShow.relative_path()<<"\n"
<<"parent_path() = "<< pathToShow.parent_path()<<"\n"
<<"filename() = "<< pathToShow.filename()<<"\n"
<<"stem() = "<< pathToShow.stem()<<"\n"
<<"extension() = "<< pathToShow.extension()<<"\n";

Here’s an output for a file path like "C:\Windows\system.ini":

exists() = 1
root_name() = C:
root_path() = C:\
relative_path() = Windows\system.ini
parent_path() = C:\Windows
filename() = system.ini
stem() = system
extension() = .ini

What’s great about the above code?

It’s so simple to use! But there’s more cool stuff:

For example, if you want to iterate over all the elements of the path just write:

int i =0;
for(constauto& part : pathToShow)
cout
<<"path part: "<< i++<<" = "<< part <<"\n";

The output:

path part: 0 = C:
path part: 1 = \
path part: 2 = Windows
path part: 3 = system.ini

We have several things here:

  • the path object is implicitly convertible to std::wstring or std::string. So you can just pass a path object into any of the file stream functions.
  • you can initialize it from a string, const char*, etc. Also, there’s support for string_view, so if you have that object around there’s no need to convert it to string before passing to path. PDF: WG21 P0392
  • path has begin() and end() (so it’s a kind of a collection!) that allows iterating over every part.

What about composing a path?

We have two options: using append or operator /=, or operator +=.

  • append - adds a path with a directory separator.
  • concat - only adds the ‘string’ without any separator.

For example:

fs::path p1("C:\\temp");
p1
/="user";
p1
/="data";
cout
<< p1 <<"\n";

fs
::path p2("C:\\temp\\");
p2
+="user";
p2
+="data";
cout
<< p2 <<"\n";

output:

C:\temp\user\data
C:\temp\userdata

What can we do more?

Let’s find a file size (using file_size):

uintmax_tComputeFileSize(const fs::path& pathToCheck)
{
if(fs::exists(pathToCheck)&&
fs
::is_regular_file(pathToCheck))
{
auto err = std::error_code{};
auto filesize = fs::file_size(pathToCheck, err);
if(filesize !=static_cast<uintmax_t>(-1))
return filesize;
}

returnstatic_cast<uintmax_t>(-1);
}

Or, how to find the last modified time for a file:

auto timeEntry = fs::last_write_time(entry);
time_t cftime = chrono::system_clock::to_time_t(timeEntry);
cout
<< std::asctime(std::localtime(&cftime));

Isn’t that nice? :)

As an additional information, most of the functions that work on a path have two versions:

Let’s now take a bit more advanced example: how to traverse the directory tree and show its contents?

Traversing a path

We can traverse a path using two available iterators:

  • directory_iterator
  • recursive_directory_iterator - iterates recursively, but the order of the visited files/dirs is unspecified, each directory entry is visited only once.

In both iterators the directories . and .. are skipped.

Ok… show me the code:

voidDisplayDirTree(const fs::path& pathToShow,int level)
{
if(fs::exists(pathToShow)&& fs::is_directory(pathToShow))
{
auto lead = std::string(level *3,'');
for(constauto& entry : fs::directory_iterator(pathToShow))
{
auto filename = entry.path().filename();
if(fs::is_directory(entry.status()))
{
cout
<< lead <<"[+] "<< filename <<"\n";
DisplayDirTree(entry, level +1);
cout
<<"\n";
}
elseif(fs::is_regular_file(entry.status()))
DisplayFileInfo(entry, lead, filename);
else
cout
<< lead <<" [?]"<< filename <<"\n";
}
}
}

The above example uses not a recursive iterator but does the recursion on its own. This is because I’d like to present the files in a nice, tree style order.

We can also start with the root call:

voidDisplayDirectoryTree(const fs::path& pathToShow)
{
DisplayDirectoryTree(pathToShow,0);
}

The core part is:

for(autoconst& entry : fs::directory_iterator(pathToShow))

The code iterates over entries, each entry contains a path object plus some additional data used during the iteration.

Not bad, right?

Of course there’s more stuff you can do with the library:

  • Create files, move, copy, etc.
  • Work on symbolic links, hard links
  • Check and set file flags
  • Count disk space usage, stats

Today I wanted to give you a general glimpse over the library. As you can see there are more potential topics for the future.

More resources

You might want to read:

Summary

I think the filesystem library is an excellent part of the C++ Standard Library. A lot of time I had to use various API to do the same tasks on different platforms. Now, I’ll be able to just use one API that will work for probably 99.9% cases.

The feature is based on Boost, so not only a lot of developers are familiar with the code/concepts, but also it’s proven to work in many existing projects.

And look at my samples: isn’t traversing a directory and working with paths so simple now? I am happy to see that everting can be achieved using std:: prefix and not some strange API :)

C++17 in details: Parallel Algorithms

$
0
0

C++17 features, simplifications

Writing multithreaded code is hard. You’d like to utilize all of the machine’s processing power, keeping code simple and avoid data races at the same time.

Let’s see how C++17 can make writing parallel code a bit easier.

Intro

With C++11/14 we’ve finally got threading into the standard library. You can now create std::thread and not just depend on third party libraries or a system API. What’s more, there’s also async processing with futures.

For example, in 2014 I wrote about using async tasks in this article: Tasks with std::future and std::async .

Multithreading is a significant aspect of modern C++. In the committee, there’s a separate “SG1, Concurrency” group that works on bringing more features to the standard.

What’s on the way?

  • Coroutines,
  • Atomic Smart pointers,
  • Transactional Memory,
  • Barriers,
  • Tasks blocks.
  • Parallelism
  • Compute
  • Executors
  • Heterogeneous programming models support
  • maybe something more?

And why do we want to bring all of those features?

There’s a famous talk from Sean Parent about better concurrency. It was a keynote at CppNow 2012, here’s a recent version from 2016 from code::dive 2016.

Do you know how much processing power of a typical desktop machine we can utilize using only the core version of C++/Standard Library?

50%,
100%?
10%?

Sean in his talk explained that we can usually access only around 0,25% with single-threaded C++ code and maybe a few percent when you add threading from C++11/14.

So where’s the rest of the power?

GPU and Vectorization (SIMD) from CPU.

GPU powerCPU vectorizationCPU threadingSingle Thread
75%20%4%0,25%

Of course, some third party APIs allow you to access GPU/vectorization: for example, we have CUDA, OpenCL, OpenGL, vectorized libraries, etc. There’s even a chance that your compiler will try to auto-vectorize some of the code. Still, we’d like to have such support directly from the Standard Library. That way common code can be used on many platforms.

With C++11/14 we got a lot of low-level features. But it’s still tough to use them effectively. What we need is an abstraction. Ideally, code should be auto-threaded/parallelized, of course with some guidance from a programmer.

C++17 moves us a bit and allows to use more computing power: it unlocks the auto vectorization/auto parallelization feature for algorithms in the Standard Library.

Plus of course, not everything can be made parallel/multi threaded as there’s Amdahl’s law. So always using 100% (110% with CPU boost :)) of the machine power is only a theoretical case. Still, it’s better to strive for it rather than write everything single-threaded.

The Series

This post is the seventh in the series about C++17 features.

The plan for the series

  1. Fixes and deprecation
  2. Language clarification
  3. Templates
  4. Attributes
  5. Simplification
  6. Library changes - Filesystem
  7. Library changes - Parallel STL (today)
  8. Library changes - Utils (soon + 1)
  9. Wrap up, Bonus

Just to recall:

First of all, if you want to dig into the standard on your own, you can read the latest draft here:

N4659, 2017-03-21, Draft, Standard for Programming Language C++ - from isocpp.org.

Also, you can grab my list of concise descriptions of all of the C++17 - It’s a one-page reference card:

Links:

And the books:

OK, let’s discuss the parallel algorithms!

Overview

I’ve already mentioned the reasoning why we want to have so many ‘tools’ for multithreading/computing in the Standard.

The TS paper describing what was merged into the Standard: P0024R2

The new feature looks surprisingly simple from a user point of view. You just have a new parameter that can be passed to most of the std algorithms: this new parameter is the execution policy.

std::algorithm_name(policy,/* normal args... */);

I’ll go into the detail later, but the general idea is that you call an algorithm and then you specify how it can be executed. Can it be parallel, maybe vectorized, or just serial.

That hint is necessary because the compiler cannot deduce everything from the code (at least not yet :)). We, as authors of the code, only know if there are any side effects, possible race conditions, dead locks, or if there’s no sense in running it parallel (like if you have a small collection of items).

Current implementation

I hope this article will be soon updated, but for now, I have bad news.

Unfortunately, as of today, any of the major compilers support the feature.

Hovewer you can play with the following implementations/API’s:

Execution policies

The execution policy parameter will tell the algorithm how it should be executed. We have the following options:

  • sequenced_policy - is an execution policy type used as a unique type to disambiguate parallel algorithm overloading and require that a parallel algorithm’s execution may not be parallelized.
    • the corresponding global object is std::execution::seq
  • parallel_policy - is an execution policy type used as a unique type to disambiguate parallel algorithm overloading and indicate that a parallel algorithm’s execution may be parallelized.
    • the corresponding global object is std::execution::par
  • parallel_unsequenced_policy - is an execution policy type used as a unique type to disambiguate parallel algorithm overloading and indicate that a parallel algorithm’s execution may be parallelized and vectorized.
    • the corresponding global object is std::execution::par_unseq

Note that those are unique types, with their corresponding global objects. It’s not just an enum.

Sequential execution seems obvious, but what’s the difference between par and par_unseq?

I like the example from Bryce Adelstein’s talk:

If we have a code like

double mul(double x,double y){
return x * y;
}

std
::transform(
// "Left" input sequence.
x
.begin(), x.end(),
y
.begin(),// "Right" input sequence.
z
.begin(),// Output sequence.
mul
);

The sequential operations that will be executed with the following instructions:

load x[i]
load y
[i]
mul
store
into z[i]

With the par policy the whole mul() for the i-th element will be executed on one thread, the operations won’t be interleaved. But different i can be on a different thread.

With par_unseqmul() each operation can be on a different thread, interleaved. In practice it can be vectorized like:

load x[i... i+3]
load y
[i...i+3]
mul
// four elements at once
store
into z[i...i+3]

Plus, each of such vectorized invocation might happen on a different thread.

With par_unseq function invocations might be interleaved, so it’s not allowed to use vectorized unsafe code: like using mutexes, memory allocation… More on that here: @cppreference.

Also, the current approach allows to provide nonstandard policies, so compiler/library vendors might be able to provide their extensions.

Let’s now see what algorithms were updated to handle the new policy parameter.

Algorithm update

Most of the algorithms (that operates on containers/ranges) from the Standard Library can handle execution policy.

What have we here?

  • adjacent difference, adjacent find.
  • all_of, any_of, none_of
  • copy
  • count
  • equal
  • fill
  • find
  • generate
  • includes
  • inner product
  • in place merge, merge
  • is heap, is partitioned, is sorted
  • lexicographical_compare
  • min element, minmax element
  • mismatch
  • move
  • n-th element
  • partial sort, sort copy
  • partition
  • remove + variations
  • replace + variations
  • reverse / rotate
  • search
  • set difference / intersection / union /symmetric difference
  • sort
  • stable partition
  • swap ranges
  • transform
  • unique

The full list can be found here: @cppreference.

A simple example:

std::vector<int> v = genLargeVector();

// standard sequential sort
std
::sort(v.begin(), v.end());

// explicitly sequential sort
std
::sort(std::seq, v.begin(), v.end());

// permitting parallel execution
std
::sort(std::par, v.begin(), v.end());

// permitting vectorization as well
std
::sort(std::par_unseq, v.begin(), v.end());

New algorithms

A few existing algorithms weren’t ‘prepared’ for parallelism, but instead we have new, similar versions:

  • for_each- similar to std::for_each except returns void.
  • for_each_n - applies a function object to the first n elements of a sequence.
  • reduce - similar to std::accumulate, except out of order execution.
  • exclusive_scan - similar to std::partial_sum, excludes the i-th input element from the i-th sum.
  • inclusive_scan - similar to std::partial_sum, includes the i-th input element in the i-th sum
  • transform_reduce - applies a functor, then reduces out of order
  • transform_exclusive_scan - applies a functor, then calculates exclusive scan
  • transform_inclusive_scan - applies a functor, then calculates inclusive scan

For example, we can use for_each (or new for_each_n) with an execution policy, but assuming we don’t want to use the return type of the original for_each.

Also, there’s an interesting case with reduce. This new algorithm provides a parallel version of accumulate. But it’s important to know the difference.

Accumulate returns the sum of all the elements in a range (or a result of a binary operation that can be different than just a sum).

std::vector<int> v{1,2,3,4,5,6,7,8,9,10};

int sum = std::accumulate(v.begin(), v.end(),/*init*/0);

The algorithm is sequential only; a parallel version will try to compute the final sum using a tree approach (sum sub-ranges, then merge the results, divide and conquer). Such method can invoke the binary operation/sum in a nondeterministic order. Thus if binary_op is not associative or not commutative, the behavior is also non-deterministic.

For example, we’ll get the same results for accumulate and reduce for a vector of integers (when doing a sum), but we might get a slight difference for a vector of floats or doubles. That’s because floating point operations are not associative.

Summary

Is that the end for today?

Multithreading/Concurrency/Parallelism are huge topics to discover and understand. I’ll hope to return with some more examples (possibly with some working implementation in common compilers!). So for now, I’ve described only the tip of an iceberg :)

From this post, I’d like you to remember that concurrency/parallelism is one of the key areas in the C++ standard and a lot of work is being done to bring more features.

With C++17 we get a lot of algorithms that can be executed in a parallel/vectorized way. That’s amazing, as it’s a solid abstraction layer. With this making, apps is much easier. A similar thing could be achieved possibly with C++11/14 or third-party APIs, but now it’s all in the standard.

  • Do you use any other parallel libraries? CUDA? SYCL? Intel TBB? Something else?
  • Do you try to make you code multi threading or write most of the code single threaded?

Below I’ve also gatherd a few valuable resources/articles/talks so that you can learn more.

Resources

The original paper for the spec: P0024R2

The initial TS paper: PDF: A Parallel Algorithms Library | N3554

ModernesCpp articles about parallel STL:

Bryce Adelstein’s talk about parallel algorithms. Contains a lot of examples for map reduce
(transform reduce) algorithm:

And the Sean Parent talk about better concurrency in C++

C++17 STL Cookbook Book Review

$
0
0

C++17 STL Cookbook Review

C++17 is on the way, and I’m glad to see more books that stay on the bleeding edge of C++ adaptation. Today I’d like to present a book that focuses on the Standard Library.

Is this another great book?

TL; DR: Yes :) But read more to see why :)

Plus I have a bonus: Q&A with the author and a giveaway.

The Book

C++17 STL Cookbook by Jacek Galowicz

Github Repo with the samples

Currently @Amazon you can buy a printed copy, if you want a DRM-Free ebook go to Pack Publishing store: C++17 STL Cookbook.

See Jacek’s blog, and on Twitter: @jgalowicz

Also, it’s worth mentioning that Arne Mertz from Simplify C++ helped with the book, as he was the technical reviewer.

BTW: I noticed Jacek around like one year or more ago and was happy to see another Polish guy writing about C++. I was misled by his Polish sounding surname. As it turned out Jacek is German with roots in Poland, so my initial guess was not 100% correct. So, I still had to communicate in English :)

The Structure

The cookbook contains over 90 recipes, 500+ pages, full of STL content and samples.

It’s not aimed at beginners. It might be great as a second or third book after an introduction to C++.

Here’s a summary of chapters:

1: The New C++17 Features

A review of new features, with examples.

2: STL Containers

Basics of containers, erase-remove idiom, removing from a vector in O(1), accessing vector elements, keeping std::vector instances sorted, maps, implementing a simple RPN calculator with std::stack, Implementing a word frequency counter, Implementing a writing style helper tool for finding very long sentences in text with std::multimap, Implementing a personal to-do list using std::priority_queue.

3: Iterators

Introduction to iterators, Making your own iterators compatible with STL iterator categories, iterator adapters, Implementing algorithms in terms of iterators, checked iterators, zip iterator adapter

4: Lambda Expressions

Using lambdas, polymorphic lambdas with std::function, function concatenation, complex predicates with logical conjunction, transform_if using std::accumulate and lambdas, Cartesian product pairs of any input at compile time.

5: STL Algorithm Basics

Copying data between different containers, sorting, searching, removing elements, Locating patterns in strings with std::search and choosing the optimal implementation (like the Boyer-Moore searcher), sampling large vectors, Implementing a dictionary merging tool, generating permutations.

6: Advanced Use of STL Algorithms

A trie class using STL algorithms, a search input suggestion generator with tries, Fourier transform formula, ASCII Mandelbrot renderer, Building our own algorithm - split, Composing useful algorithms from standard algorithms - gather, Removing consecutive whitespace between words, compressing and decompressing strings.

7: Strings, Stream Classes, and Regular Expressions

Creating, concatenating, trimming, and transforming strings, using string_view, Reading values from user input, Counting all words in a file, I/O stream manipulators, std::istream iterators, std::ostream iterators, custom string classes by inheriting from std::char_traits, Tokenizing input with the regular expression library, Catching readable exceptions from std::iostream errors.

8: Utility Classes

Using std::ratio, chrono, optional, tuples, variant, any, smart pointers, random number engines.

9: Parallelism and Concurrency

Paralell STL, working with threads, Performing exception safe shared locking with std::unique_lock and std::shared_lock, avoiding deadlocks with std::scoped_lock, safely postponing initialization with std::call_once, using std::async, producer/consumer idiom, parallelizing the ASCII Mandelbrot renderer using std::async, Implementing a tiny automatic parallelization library with std::future.

10: Filesystem

Listing all files in directories, writing a grep-like text search tool, an automatic file renamer, disk usage counter, Calculating statistics about file types, Implementing a tool that reduces folder size by substituting duplicates with symlinks

My View

If you only skimmed the previous section, please go back and read what’s inside those ten chapters. I can wait :)

Impressed?

I am!

What’s clear is that most of the recipes are a solid, working examples/demos. Of course, there are many introduction sections to give you a background, but most of the time you just work on a small app, or tool. So those are not just tiny, theoretical, impractical code samples. If you finish a chapter, you can be sure to end with something useful.

Nor is this a reference book. You can find introductory explanations, but in general, it will teach you how to use STL efficiently by working on real problems.

Regarding the amount of experience needed to understand the chapters, it varies a lot. There is some basic stuff that everyone (after an intro to C++) should get. But there are also complicated examples where you’ll need to read the section several times (at least I had to! :)). That’s good. Having all recipes on the same level would be boring. With such mixture, everyone can find something for themselves and also have some challenge with more advanced problems.

Interesting recipes

A few of recipes that caught my attention:

Mandelbrot renderer

Mandelbrot renderer, C++17 STL Cookbook

The example is maybe complicated; I had to read it several times to understand. Still, it shows how to compose the solution using smaller blocks. So you’ll be using functions that return lambdas, complex numbers, std::transform.
You have even two variations: a basic version and the parallelized one!

Other tools/utils/demos:

  • Grep-like tool - it shows how to iterate over a directory and then scan text files (with regex).
  • Reverse Polish Notation calculator.
  • Tries and working with text/dictionaries.
  • Writing style helper tool for finding very long sentences in text with std::multimap. The text is tokenized to get sentences stats. Then a user can see what parts of text should be improved.

STL tricks

Like deleting items from an unsorted std::vector in O(1) time. Copying elements from different containers. Synchronized stdout:

staticvoid print_pcout(int id)
{
pcout
{}<<"pcout hello from "<< id <<'\n';
}

The object pcout makes sure the whole string is printed to stdout without any interruption as you could get with the standard cout.

Debugging iterators

Using _GLIBCXX_DEBUG, or (/D_ITERATOR_DEBUG_LEVEL=1) in MSVC.
It’s great that the book brings up that topic. Iterators are powerful, but they can quickly become invalid when used in the wrong way. The recipe shows how different tools can help when debugging such cases.

Functional stuff

Zips, composing functions, lambdas. Functional programming gets more and more popular, so I like that Jacek shows a few ideas in the examples.

Implementing a tiny automatic parallelization library

Mandelbrot renderer, C++17 STL Cookbook

The example shows how to distribute the sub-tasks of a problem as an automatically parallelizing asynchronous version. The lambdas returning lambdas are a bit hardcore, but it works :) The example uses this for strings operations, but you can adapt the tiny library for any domain.

Going back to a general overview:

Jacek also conveys a crucial message throughout the book. For example:

“At this point, we are using STL data structures so intuitively that we can nicely avoid pointers, raw arrays, and other crude legacy structures.”

Similar messages appear in several parts of the book. When you know STL you can build your apps much faster, and more safely, and compose code as if you were sticking Lego blocks together. It’s also a modern style of C++ - not using raw code structures or reinventing everything from scratch.

All in all, great stuff.

Plus, as always its cookbook style makes it easy to read, which I like.

But wait.

Before we go to the summary, I’d like to show you a little interview with the author:

Q&A with the author

Bartek: How did you come up with the idea for the book? Why did you want to write about STL?

Jacek: It was actually not my own idea to write a book at all and specifically about the STL. Nitin Dasan, a very nice Acquisition Editor at Packt Publishing, approached me and asked very directly if I was interested in writing a book for them. Back then, the title “C++17 STL Cookbook” was already fixed.
At that time I was unemployed because my former employer shut down the whole site I was associated to. Since I was seeking to become self-employed rather than just looking for jobs somewhere else, writing my own book looked like a great opportunity. The next step was compiling a list of ~90 recipes that I would write for the book, which Packt then accepted and sent me a contract.
While the book title and format (a cookbook with recipes) were fixed already, I still had a lot of freedom: What would the recipes be about and how would they use C++17 and the STL?
I tried to do as many things with the STL as possible. As you noticed in your review already, I did even avoid for-loops. My idea was to demonstrate that the STL is not only a library of neat little helpers but actually a foundation of building blocks whole applications can and should build on. Everyone who does not realize this tends to reinvent the wheel here and there. If you rewrite something that the STL already provides, you ditch the fact that all these algorithms and data structures are usually well designed, well tested, well performing, and keep your code well readable and maintainable. C++ programmers should perceive the STL as standard building blocks that are just linked differently in every C++ program (this perspective is now pointedly oversubscribed).
The reader might find that sometimes extreme. But then, he/she is completely free to pick what he/she liked and leave the rest. My hope is that this books really shows the audience something new and that it is inspiring.

Bartek: What was the hardest part of writing the book?

Jacek: The recipes in the book are all about C++17 and the STL. This means that they should only require a C++17 capable compiler and the STL. It was hard to find about 90 meaningful and interesting example problems and applications that are short but self-contained enough, as they need fit into the typical 4-8 pages recipe format. It would have been easier to find nice real life examples if the STL was already including features like networking and so on. Including external libraries would have missed the point of the book and might have made it harder for users of different operating systems to follow them, so I strictly avoided that.

Bartek: What’s your favourite feature of C++17 (a language or STD library feature)?

Jacek: My favorite little list of new features is:

  • Lambda expressions: These are not new to C++17, but I love them as I recently also learned Haskell and got pretty fascinated by functional programming style. Lambda expressions in C++ enable for adapting many beautiful concepts from there and using them to make the low-level code more generic and maintainable.
  • Parallel algorithms: It blew me away when I heard about this for the first time! Parallelizing code portably just by prepending another parameter in existing STL algorithm calls - this is fantastic.
  • Iterator sentinels: I do often implement my own iterators for all kinds of low-level things. This became even easier and more flexible since the end-iterator does not have to be of the same type as the begin-iterator any longer.
  • Structured bindings: I use tuples a lot and structured bindings are really helping with keeping code readable.
  • Automatic template type deduction: Finally I do not always have to implement make_xxx(…) helper functions any longer for determining the template types of classes that shall only depend on from what kind of type I construct them!
  • Inline member variables: Some libraries are best implemented as header-only and this new feature is quite an enabler in that regard.

Bartek: What other C++17 books would you like to see?

Jacek: In general, I love books that make me change my thinking and shake me out of developing in old patterns I was always used to.
I would especially love to see more books from 2 groups of developers:

  • Library developers: Libraries are what really empowers the application programmer, it’s not just the rising amount of language features. In general, what makes a library great is when it is easy to use correctly, hard to use incorrectly, and when it is fast for as many different use cases as possible. More C++ specific books on that topic would be great.

  • Embedded developers: Using C++ in the embedded area seems to come more and more into fashion. Being an embedded/OS developer myself, I often feel that I need to pioneer a lot of things (although there are also a lot of great libraries for different situations already!). More literature that expands horizons in that area would be great.

Summary

Final mark: 5/5

Pros:

  • Practical, full of examples, demos, little utilities
  • Details of the approach, even with pictures and diagrams! :)
  • Cookbook style, read what you want
  • Shows how to make code compact
  • Shows how to use STL as building block for an app/problem
  • Focuses on modern C++, avoids using raw code style: pointers, C-style arrays, even raw loops
  • Introduces functional concepts

Cons:

  • I’d like to see more :)
  • Nitpicking: some samples might not work yet if your compiler is not in the C++ latest mode, or even experimental (will change soon).

Another solid book about C++17 just before the C++17 Standard is announced!

Not aimed at beginners, but if you have some experience with C++, you’ll find something for yourself. The chapters are structured to be as clear as possible, with introductions and even pictures and diagrams.

Some time ago I had reviewed C++ Modern Programming Cookbook. These two books don’t compete much with each other, and I’d suggest reading them both. “C++ Modern Programming” is focused on all levels of experience (also for ‘almost’ beginners), while “C++17 STL Cookbook” is for an intermediate/expert level. You’ll find some good introduction in the first book, and then you can continue forward and gain more from the second book.

Giveaway

As usually, together with Packt Publishing, we have three “C++17 STL Cookbookebooks to give!

All you have to do is to be a subscriber to my mailing list, and add a comment below. Plus you can reshare this review to get more chances to win…
You’ll find everything in the giveaway tool below:

C++17 STL Cookbook Giveaway

We’ll randomly draw 3 winners on September 11th (in the morning, Poland Time); it will be announced here in this post and on Twitter. So you have two weeks to take action :)

To help you with a comment idea you can think about the following questions:

  • What’s you favorite C++17 feature?
  • Do you use STL library or something else?
  • What recipes for modern C++ would you like to read more?
  • What other books you’d suggest for modern C++?

C++17 in details: Standard Library Utilities

$
0
0

C++17 features, stl utils

The new C++ standard brings many useful additions to the Standard Library. So far we’ve discussed bigger features like the filesystem or parallel algorithms. Today, I want to focus on smaller, but also handy things.

For example, there are utils for handling type safe unions, replacement of void*, string searchers and much more.

Intro

What I like about C++17 is that it finally brings a lot of features and patterns that are well known but come from other libraries. For example, for years programmers have been using boost libraries. Now, many of boost sub -libraries are merged into the standard. That merging process makes the transition to the modern C++ much easier, as most of the time the code will just compile and work as expected. Not to mention is the fact that soon you won’t need any third party libraries.

Let’s have a look at the following features:

  • std::any - adapted from boost any
  • std::variant - and the corresponding boost variant
  • std::optional - boost optional library
  • std::string_view
  • Searchers for std::search
  • Plus a few other mentions

The Series

This post is the 8-th in the series about C++17 features.

The plan for the series

  1. Fixes and deprecation
  2. Language clarification
  3. Templates
  4. Attributes
  5. Simplification
  6. Library changes - Filesystem
  7. Library changes - Parallel STL
  8. Library changes - Utils (today)
  9. Wrap up, Bonus (soon)

Just to recall:

First of all, if you want to dig into the standard on your own, you can read the latest draft here:

N4659, 2017-03-21, Draft, Standard for Programming Language C++ - from isocpp.org.

Also, you can grab my list of concise descriptions of all of the C++17 - It’s a one-page reference card, pdf language features: grab it here.

Links:

And the books:

OK, let’s discuss the utils!

Library Fundamentals V1 TS and more

Most of the utilities described today (std::optional,std::any, std::string_view, searchers) comes from so called “Library Fundamentals V1”. It was in Technical Specification for some time, and with the paper “P0220R1 - Adopt Library Fundamentals V1 TS Components for C++17 (R1”) it got merged into the standard.

Support:

When I describe the features, I write “compiler” support, but when discussing library features, I should mention the library implementation. For the sake of simplification, I’ll just stick to compiler name as each common compiler (GCC, Clang, MSVC) have its separate libs.

And now the features:

std::any

A better way to handle any type and replace void*.

Node from n4562:

The discriminated type may contain values of different types but does not attempt conversion between them, i.e. 5 is held strictly as an int and is not implicitly convertible either to “5” or to 5.0. This indifference to interpretation but awareness of type effectively allows safe, generic containers of single values, with no scope for surprises from ambiguous conversions.

In short, you can assign any value to existing any object:

auto a = std::any(12);
a
= std::string("hello world");
a
=10.0f;

When you want to read a value you have to perform a proper cast:

auto a = std::any(12);
std
::cout << std::any_cast<int>(a)<<'\n';

try
{
std
::cout << std::any_cast<std::string>(a)<<'\n';
}
catch(const std::bad_any_cast& e)
{
std
::cout << e.what()<<'\n';
}

Here’s a bigger runnable sample (GCC 7.1):

Notes

  • any object might be empty.
  • any shouldn’t use any dynamically allocated memory, but it’s not guaranteed by the spec.

More info in:

MSVC VS 2017, GCC: 7.0, Clang: 4.0

std::variant

Type safe unions!

With a regular union you can only use POD types (correction: since C++11 it's possible, assuming you provide required operation like a copy constructor, move... see union declaration), and it’s not safe - for instance, it won’t tell you which variant is currently used. With std::variant it’s only possible to access types that are declared.

For example:

std::variant<int,float, std::string> abc;

abc can only be initialized with int, float or string and nothing else. You’ll get a compile time error when you try to assign something else.

To access the data, you can use:

  • std::get with index or type of the alternative. It throws std::bad_variant_access on errors.
  • std::get_if - returns a pointer to the element or nullptr;
  • or use std::visit method that has usage especially for containers with variants.

A bigger playground (GCC 7.1):

Notes:

  • Variant is not allowed to allocate additional (dynamic) memory.
  • A variant is not permitted to hold references, arrays, or the type void.
  • The first alternative must always be default constructible
  • A variant is default initialized with the value of its first alternative.
  • If the first alternative type is not default constructible, then the variant must use std::monostate as the first alternative

More info:

MSVC VS 2017, GCC: 7.0, Clang: 4.0?

std::optional

Another and elegant way to return objects from functions that are allowed to be empty.

For example:

std::optional<std::string> ostr =GetUserResponse();

if(ostr)
ProcessResponse(*ostr);
else
Report("please enter a valid value");

In the simple sample above GetUserResponse returns optional with a possible string inside. If a user doesn’t enter a valid value ostr will be empty. It’s much nicer and expressive than using exceptions, nulls, output params or other ways of handling empty values.

A better example (GCC 7.1):

Notes:

  • Implementations are not permitted to use additional storage, such as dynamic memory, to allocate its contained value. The contained value shall be allocated in a region of the optional storage suitably aligned for the type T.

More info:

MSVC VS 2017, GCC: 7.0, Clang: 4.0?

string_view

Although passing strings got much faster with move semantics from C++11, there’s still a lot of possibilities to end up with many temporary copies.

A much better pattern to solve the problem is to use a string view. As the name suggests instead of using the original string, you’ll only get a non-owning view of it. Most of the time it will be a pointer to the internal buffer and the length. You can pass it around and use most of the common string functions to manipulate.

Views work well with string operations like sub string. In a typical case, each substring operation creates another, smaller copy of some part of the string. With string view, substr will only map a different portion of the original buffer, without additional memory usage, or dynamic allocation.

Another important reason for using views is the consistency: what if you use other implementations for strings? Not all devs have the luxury to work only with the standard strings. With views, you can just write (or use) existing conversion code, and then string view should handle other strings in the same way.

In theory string_view is a natural replacement for most of const std::string&.

Still, it’s important to remember that it’s only a non-owning view, so if the original object is gone, the view becomes rubbish.

If you need a real string, there’s a separate constructor for std::string that accepts a string_view. For instance, the filesystem library was adapted to handle string view (as input when creating a path object).

Ok, but let’s play with the code (GCC 7.1):

More info:

MSVC VS 2017, GCC: 7.0, Clang: 4.0?

Searchers

When you want to find one object in a string, you can just use find or some other alternative. But the task complicates when there’s a need to search for a pattern (or a sub range) in a string.

The naive approach might be O(n*m) (where n is the length of the whole string, m is the length of the pattern).

But there are much better alternatives. For example Bayer-Moore with the complexity of O(n+m).

C++17 updated std::search algorithm in two ways:

  • you can now use execution policy to run the default version of the algorithm but in a parallel way.
  • you can provide a Searcher object that handles the search.

For now we have three searchers:

  • default_searcher
  • boyer_moore_searcher
  • boyer_moore_horspool_searcher

You can play with the example here:

  • Which version is the fastest?
  • Is this better than just std::string::find?

More info:

MSVC VS 2017.3, GCC: 7.0, Clang: 3.9?

Other Changes

  • shared_ptr with array - P0414R2: Merging shared_ptr changes from Library Fundamentals to C++17. So far unique_ptr was able to handle arrays. Now it’s also possible to use shared_ptr.
  • Splicing Maps and Sets - PDF P0083R2 - we can now move nodes from one tree based container (maps/sets) into other ones, without additional memory overhead/allocation.
  • Mathematical special functions - PDF: P0226R1
  • Improving std::pair and std::tuple - N4387) - pair/tuple obey the same initialization rules as their underlying element types.
  • Sampling - n4562: Sampling - new algorithm that selects n elements from the sequence
  • Elementary string conversions - P0067R5, new function to_chars that handles basic conversions, no need to use stringstream, sscanf, itoa or other stuff.

Summary

Did I miss something? Yes!

There are many other changes in STL that would fill another post (or I could expand the “Other Changes” section). But let’s stop for now. Note that each of those ‘small’ utils are worth a separate post, with more example, so I’ll definitely plan to do that later :)

If you want to dig deeper try to read the spec/draft or look at the official paper with changes: P0636r0: Changes between C++14 and C++17 DIS.

As I mentioned, I like that C++17 merged many useful well-known patterns into STL. There’s a high chance you’ve come across many of the features and using them in a project shouldn’t be that hard.

What do I like the most?

I think:

  • Filesystem - a significant portion of the library, that will make code much easier and common across many platforms.
  • type safe helpers: std::any, std::optional, std::variant - we can now replace void* or C style unions. The code should be safer.
  • string features: like string_view, string conversions, searchers.
  • parallelism - very powerful abstraction for threading.

Still, there’s a lot of stuff to learn/teach! I’ve just described the features, but the another part of the equation is to use them effectively. And that needs experience.

  • What are your favourite features from C++17 STL?
  • What have I missed? What else should be in my C++17 posts?
  • Have you already used any/optional/variant, for example from boost?

Learning from bugs and PVS-Studio Team

$
0
0

PVS Studio Resources

Real life:

Fixed 1 out of 99 bugs in a project. 117 to go…

Have you experienced something similar? Although it’s impossible to write bug-free code, there are tools and practices to lower the rate of mistakes.

Today, I’d like to run through a gigantic list of freely available resources from the PVS-Studio Team who works with bugs analysis on a daily basis.

Promo note: This article is sponsored by PVS Studio. Written by me.

Intro

The Russian team behind PVS-Studio is, I think, well known in our C++ world. They not only maintain the static code analysis tool, but they also run a few blogs with tons of good stuff about programming.

PVS-Studio logo

And they have that funny rainbow-puking unicorn as their logo! :)

With this post, I don’t want just to sell info about their tool. I believe they have much more to offer.

What I like about the PVS-Studio Team is that they share their experience with the community. Plus, they have a unique, sometimes controversial style of writing, so it’s also a good read (for example a year ago they took over the internet :)).

From hundreds of articles I’ve selected a few and categorized them.

Here are the three main sections:

  • Code analysis: How it works? Why is it so important? Dynamic or static?
  • Repository of bugs: Whenever you created a bug, for sure you’re not the first and many before you have might experienced a similar problem. So why not learn from the “past” and other projects?
  • Guidelines: The PVS-Studio Team also does a lot of bug analysis, and they share many guidelines that can be directly applied to your code.

But first, let’s introduce the company.

About PVS

Andrey Karpov (@Code_Analysis) and Evgeniy Ryzhkov (@evg_viva64) started the PVS-Studio company around 11 years ago, in 2006.

On 31st December Viva64 1.00 was released! The tool would help you porting projects from 32 bit into 64 on Windows.

With a lot of bumps on their entrepreneurial road, changing plans and financial struggles they managed to pursue their goals and improve the product. Currently, the company has more than 20 people on board, and the analyzer helps with bug detection in C++ projects, Windows, and Linux. Recently the tool can also work with C#. PVS-Studio is written in C, C++, and C#.

If you want to read the whole story behind the product, read here: PVS-Studio project - 10 years of failures and successes or Founder’s Advice. Evgeniy Ryzhkov .

Understanding the static analysis

When you compile a source file, you might end up with a lot of compiler warnings. A common practice is to fix them and have zero warnings policy.

But, is that enough to have a safe and bug-free code? Definitely not.

So, what is the static analysis and why it’s better than the compiler warnings?

You can read more in this article. But briefly:

  • Code analysis is not the compiler’s primary task.
  • Using different compilers for analysis is difficult yet advisable.
  • Compilers span a narrow range of most common bugs.
  • Static analyzers only specialize in code analysis.
  • Static analyzers provide a wide range of diagnostic rules.
  • Certain diagnostics imply inevitable false positives due to their nature.
  • You can use different analyzers independently, regardless of what compiler you use.

As you can see static analyzers also works on source files, but they specialize in picking little nuances and reporting as many hints as possible. Of course, such processing takes more time than just the compilation.

Here are some articles that describe the process and the approach in detail:

It’s also worth mentioning that even John Carmack wrote/spoken about the importance of code analysis. For example, you can read his article here Static Code Analysis - by John Carmack! (reposted on PVS blog).

Ok, so far we've mentioned the static analysis, but why not use only dynamic bug deduction?

For instance, when you use Valgrind you can find a lot of leaks, Access Violations or other runtime errors.

In the post: Static and Dynamic Code Analysis Andrey Karpov explains that we should use both tools as they usually complement each other. Not to mention that it’s not that easy to execute the dynamic analysis, as you need the infrastructure, tests and often need to run the binaries with a different set of input data. More detail in another post: terminology: Dynamic code analysis.

Of course, PVS Studio has a few competitors in the field of C++ code analysis. For instance, You can read about them here: An Overview of Static Analyzers for C/C++ Code. Or a comparison with freely available CppCheck: Cppcheck and PVS-Studio compared and Why I Dislike Synthetic Tests.

I haven’t used the paid tools much, but around a year ago I started using code analysis from Visual Studio. It usually reports like 10…20x more warnings than the compiler! While it’s probably not the best tool around, you can use the Community version for free. PVS Team made a few comparisons against their reports: Comparing Analysis Capabilities of PVS-Studio and Visual Studio 2015’s Analyzer.

The database of bugs

As one of their promotional strategies, the PVS-Studio Team analyses a lot of open source projects. They’ve managed to build a large list of common bugs and error-prone patterns. The approach created “the database of bugs.”

The database contains bug id, description, examples:

PVS-Studio, database of bugs

You can see a list of projects that exposed the bug, and read an expanded description. This might be a useful and educative resource.

The bugs repository is located here:
Errors detected in Open Source projects by the PVS-Studio developers through static analysis
.

The company claims to have found 10k bugs: We found over 10000 bugs in various open-source projects.

BTW: I’ve just got an idea that such a bug list provides a good way to start doing open source projects. Just pick a bug/warnings, see if it’s still there in the project and submit a fix.

Projects checked

As mentioned, the PVS-Studio Team has reviewed a lot of projects, here’s a list of a few that caught my attention:

Guidelines

What can we do with the analyzed bugs?

It would be best to learn from them and avoid error prone patterns.

The PVS-Studio Team gives another valuable resource: guidelines.

For example, If you’re brave you can read all of the: The Ultimate Question of Programming, Refactoring, and Everything. That’s a mega post with guidelines about programming. I had already mentioned it in my article last year: C++ (Core) Coding Guidelines:

The book (the article) covers 42 topics. In spite of the simple titles of the
chapters, the bugs found are various and non-standard. In
addition to that, the text provides a lot of links to interesting
materials that give more details on topics. To make more use of this
book, please don’t hurry and go to the links provided.

For example, we have tips on modern C++ “38. Use nullptr instead of NULL from now on” and “15. Start using enum class in your code, if possible”. BTW: about modern C++ they have a separate article: How to avoid bugs using modern C++.

But the “Ultimate… ” article also contains more complex and practical cases:

  • “11. Don’t try to squeeze as many operations as possible in one line”:
    • For example return c * ((t = t / d - 1) * t * t + 1) + b; it’s not only hard to read, but also contains what might lead to undefined behaviour (order of params evaluation).
  • “12. When using Copy-Paste, be especially careful with the last lines” - an interesting effect where statistically there’s a high chance of making a typo/mistake.
  • “13. Table-style formatting”
  • “25. Do not compare ‘this’ to nullptr anymore”:
  • “32. Dangerous printf”
    • If you still need to use printf don’t write code like printf(File.getloc().name().c_str()); as it might lead to security issues.
  • “35. Adding a new constant to enum don’t forget to correct switch operators.”

The whole guide focuses on practical patterns, even code formatting. Sometimes it’s on a different level than high-level guidelines like C++ Core Guidelines. Worth checking that list against your code.

Also, as the PVS-Studio originally started as a tool for checking 64-bit errors, the Team prepared a detailed guide on 64-bits: Lessons on development of 64-bit C/C++ applications (single file).

Another article worth mentioning:

  • The Evil within the Comparison Functions - in a sample of simple code we’ll just see simple statements like if (a > b) { } or if (checkVars()) { }. Clean and nice. But the reality is different as we often see a code with 2… 3 or even more lines of conditions, joined with some logical operation. It’s so easy to make an error in such expressions.

Q&A with Andrey Karpov, CTO?

BF: How did you start with programming? (Was C++ your first language?)

Andrey : My first computer was a soviet Apogee BK 01 (home computer).

https://geektimes.ru/post/279126/

https://ru.wikipedia.org/wiki/%D0%90%D0%BF%D0%BE%D0%B3%D0%B5%D0%B9_%D0%91%D0%9A-01

Unfortunately, I can’t give a description in English. Well, this is approximately the same as ZX Spectrum, only simpler. I had only 2 languages for it: Basic and Assembler. There were other languages for it, but I had only those tapes. So everything has been predetermined without me:).

In the beginning I learned Basic. It had plenty of restrictions. And when it wasn’t enough of the abilities, I learned and started programming in Assembler. Then there was a 80286 computer, learning Pascal, etc., but that’s another story. I got to know C++ (Borland C++ 3.1) only in the university and was learning it myself, as it wasn’t taught during the first years.

BF: Do you still write code for your tool or you’re mostly responsible for the management?

Andrey : I like to code in C++, but I haven’t participated in writing the analyzer core for about a year. I just don’t have time for this. Basically, I run Visual C++, when I need to try something. Usually this is related to users support or there’s something you should experiment when writing an article.

BF: Why C++is so hard to analysis?

Andrey :You need to consider a lot of subtleties. Having selected the wrong pattern, you need to make many exceptions. A simple example:

a = a;

Does it seem to be a typo or an unequivocal error? Not at all. This makes sense if these are volatile variables. It is not necessary to issue a warning. Or it is necessary to check whether this is the implementation of the macro with names such as UNREFERENCED_PARAMETER. If it’s such a macro, then it is not necessary to complain. And so on. And it was only the simplest case. In complex diagnostics, special cases are numbered in tens. The way static analyzers fight against false positives, and why they do it: https://www.viva64.com/en/b/0488/

It is necessary to support all new and new constructions that appear in C++xx (C++11, C++14, C++16, …).

Moreover, in C++, there is such a horror as goto and switch. These are very complex operators for analysis. They spoil everything. :)

Summary

I hope you weren’t too bored by this sponsored post.

As you can see marketing strategies, like that of PVS-Studio, can be also fun and provide real value to users/readers. With the bug database, a multitude of articles about checked projects and the resulting guidelines, you can learn a lot about coding.

C++17 in detail: Summary & Bonus

$
0
0

C++17 features, summary

The last post in the series about C++17 (STL utils) was posted on 4th September. It happened to be just two days before the final C++17 spec was approved! :)

C++17 is formally approved
2017-09-06 by Herb Sutter
herbsutter.com/2017/09/06/c17-is-formally-approved/

In this post, I’d like to make a little summary, and I also have a bonus for you :)

The Series

We ended up with 8 articles:

  1. Fixes and deprecation
  2. Language clarification
  3. Templates
  4. Attributes
  5. Simplification
  6. Library changes - Filesystem
  7. Library changes - Parallel STL
  8. Library changes - Utils

And today is the Wrap-up, Bonus.

About C++17

Do you like the new standard?

Probably we expected a bit more. Still, it’s a really decent update! The committee made a change when comes to the “shipping” process. Rather than waiting for all the great features to be completed (as it happened with C++11) they now set a deadline. If a feature is not done for a specific schedule, then it will just move to the new spec - so in next 3 years.

I am convinced the features we get with the release make a real change of how we write cpp code. So now we have to learn how to use the new stuff effectively.

What I like the most:

  • constexpr if - very powerful tool, allows you to write template/metaprogramming code in a similar way to the ‘standard’ code.
  • Structured bindings - moves C++ closer to dynamic languages
  • Template argument deduction for class templates and other template features
  • Filesystem - a significant portion of the library, that will make code much easier and common across many platforms.
  • Type safe helpers: std::any, std::optional, std::variant - we can now replace void* or C style unions. The code should be safer.
  • String features: like string_view, string conversions, searchers.
  • Parallelism - very powerful abstraction for threading.

Thoughts on the series

First of all thanks for reading my content! The whole series got very popular, as each post got around 15..20k views in the first weeks. Some even more (like Code Simplification got 50k views! or fixes and deprecation 28k views!).

For me, it was not only a great chance to learn about the standard, but I’m also more convinced that I like writing such content. Reading the spec, gathering new info, writing examples… great fun! :)

Ok… but I know you’re waiting for the bonus… so here it is :)

Bonus

As I mentioned in my newsletter, I could spend some time and merge all of the posts into one ebook.

And this is what I did :)

The ebook is mostly the merge, but with some little updates, reorganization. The format will make it much easier to read than browsing through the posts.

I ended with more than 50 pages!

Hmm… maybe I should sell it for 1000$ and get rich quickly? :)

OK, maybe 1k $ would be too much. So I decided just to make one requirement to have this ebook: just subscribe to my mailing list, the book then comes for free. (existing subscribers got an email with the link to download, so no action needed for them).

C++17 in detail, by Bartlomiej Filipek

Signup here and get the book

Let me know if you find typos, mistakes in the text. I am happy to update the text, and I’ll send an update.

The Expressive C++17 Coding Challenge

$
0
0

The Expressive C++17 coding challenge

Let’s put C++17 in practice!

One of the good ways to do it is to take part in a coding challenge.
So together with Jonathan Boccara from Fluent C++ we invite you to participate in “The Expressive C++17 coding challenge”.

The Expressive C++17 coding challenge

Jonathan made a few contests on his blog (for example this one), and I thought it might be fun to do something similar for C++17. Moreover, on his blog there's a lot about expressive C++, which is a perfect match for the C++17 coding style. That’s why we joined our forces :)

Here’s Jonathan's corresponding post!

The purpose of this challenge is to write a piece of code that contains as many features of C++17 as possible, and that is as clear as possible.

The case

The task proposed in the challenge is to write a command line tool that takes in a CSV file, overwrites all the data of a given column by a given value, and outputs the results into a new CSV file.

More specifically, this command line tool should accept the following arguments:

  • the filename of a CSV file,
  • the name of the column to overwrite in that file,
  • the string that will be used as a replacement for that column,
  • the filename where the output will be written.

For instance, if the CSV file had a column “City” with various values for the entries in the file, calling the tool with the name of the input file, City, London and the name of output file would result in a copy of the initial file, but with all cities set equal to “London”:

Expressive C++17 coding challenge sample

Here are small input and output CSV files that can serve as a test case.

  • input
  • output
  • command line Tool.exe input.csv City London output.csv

Here is how to deal with edge cases:

  • if the input file is empty, the program should write “input file missing” to the console.
  • if the input file does not contain the specified column, the program should write “column name doesn’t exist in the input file” to the console.

In both cases, there shouldn’t be any output file generated.

And if the program succeeds but there is already a file having the name specified for output, the program should overwrite this file.

Of course, we could go further with that idea. For example, the replacement would happen only when a text in a column matches some condition. But let’s focus on the core parts for now.

The rules of the challenge

To win the challenge, your code must have as many features of C++17 as possible. Please write all those you’ve used in a comment section at the top of your .cpp file.

To win the challenge, your code must also be as clear as possible (you can write about what you did to achieve this too if you want).

To submit a solution, paste your code into this empty coliru link (it has the C++17 compilation flag) to make sure it compiles, click the “Share!” button and add the generated link to the comment section of this post, or on Jonathan ’s blog.

The gcc options: g++ -std=c++1z -O2 -Wall -pedantic -pthread main.cpp -lstdc++fs && ./a.out (so with threads and filesystem).

To be registered in the contest, add your email address at the beginning of your code so that we can get in touch with you. We’ll be sure to add you to the mailing lists of bfilipek.com and Fluent C++ (you can unsubscribe at any time, but you’ll get notified when the results come out).

If you don’t want to display your email address on your solution, you can send it to Jonathan or me privately. The same goes for your entire solution if you’d like.

The contest ends on the 15th of October at midnight GMT. So the 15th is ok, the 16th is too late. The results will be published on the 23rd of October. We’ll discuss the best solutions in the summary post(s).

If two people submit an equivalent solution, the first one wins.

Notes / Remarks

  • Don’t use any third party libraries, the code should call only STD library.
  • We use GCC 7.2 so parallel algorithms aren’t supported.

Experimentally you can code using tech.io basic playground:

But please save your code often. Be sure to copy the final code into Coliru and prepare a shared link. The Tech.io playground is here only for you to try.

Wrap-up

Let’s have some fun with C++17!

To help you with the learning here are some resources:

Should you have any question or feedback, don’t hesitate to get in touch with either one of us.

We’re waiting for your submissions & happy coding! :)

Cpp Con 2017 Notes

$
0
0

Notes from Cpp Con

Have you been at Cpp Con this year?

I haven’t, but still I plan to watch some good C++ talks. Can you help me a bit and add your notes?

Last update: 9th October 2017

Intro

Cpp Con 2017 is over and recently the videos from the talks started to appear. It’s a good time to refresh the knowledge about C++ and learn something new. I am especially interested in talks about new things, industry problems and experience with using C++ in production.

I am using open repository to collect notes, so just follow: github/fenbf/cppcon2017_notes. Submit your changes so we can make a larger collaborative post.

First of all here are the official links:

And the summary:
Thanks / 2018 Dates / 2017 Trip Reports | cppcon

And some of the trip reports:

Trip Reports

Talks

Here’s a list of talks with a summary and they key points (to be updated!)

Bjarne Stroustrup “Learning and Teaching Modern C++”

CppCon 2017: Bjarne Stroustrup “Learning and Teaching Modern C++” - YouTube

  • “We’re all teachers” - this is a good talk, especially for all the people who teach other how to code: but not only bloggers, proffesors… but even for you when you advice/help your collegues from time to time.
  • C++ was tought sometimes in a messy way, so we can do better.
  • “if you write your own linked list (and use it in production code) you’re cool”. We cannot teach that way any more. It’s just better to use STL.
  • Simple example: Why range for loop is better than the old for loop (with i as the index).

Matt Godbolt “What Has My Compiler Done for Me Lately? Unbolting the Compiler’s Lid”

CppCon 2017: Matt Godbolt “What Has My Compiler Done for Me Lately? Unbolting the Compiler’s Lid”

PDF slides

  • Matt’s story: why he loves asm and how he started with Compiler Explorer.
  • ASM 101, it’s really not that hard to read some of the basic code. It might help you to understand your code better.
  • Examples of how compilers might be smart. Math stuff mostly, but intresting to see how it’s usually best to rely on the code generation.
  • Tech stack behind Compiler Explorer

Carl Cook “When a Microsecond Is an Eternity: High Performance Trading Systems in C++”

CppCon 2017: Carl Cook “When a Microsecond Is an Eternity: High Performance Trading Systems in C++”

PDF slides

  • High Frequency Trading in general earns money by buying and selling very often, and looking for small price changes. The success is to be faster than the competition.
    • Usually they have like 2.5us to react and do the trade… it’s less time than a light travelling from top of BBurj Khalifa to the bottom!
  • C++ is used because it’s a relatively abstract language, gives zero cost overhead over the abstraction over the hardware.
    • They often have to check the generated code, so it’s no coincidence that Compiler Explorer comes from that industry… check Matt’s talk.
  • Techniques covered (for the hot path, not for the whole code)
    • removing branch prediction, using templates and compile time configuration (to avoid dynamic polimorphism, virtual method costs, eliminate branches)
    • Lambdas are very expressive and still give a lot of power, they might be inlined.
    • Be carefull about memory allocations, use pool of pre allocated objects, delete on other thread
    • Carl advices to use exceptions (but not for the control flow!), they cost zero if they didn’t throw.
    • Multithreading is usually avoided for low latency code, the hot path. They even disable all other cores and use just one.
    • Use data wisely, if you read something from the memory, use full cache lines
    • There’s a comparision of various hash map approaches
    • in order to keep the cache hot, they might run simulations and only from time to time do the actual trade/response.
  • As usually: measure measure measure :)
    • They setup a production system to measure it reliably

Contributors

Summary

todo… :)

How not_null can improve your code?

$
0
0

not_null examples

One of the key points of modern C++, as I observe, is to be expressive and use proper types. For example, regarding null pointers, rather than just writing a comment:

voidFoo(int* pInt);// pInt cannot be null

I should actually use not_null<int *> pInt.

The code looks great now, isn’t it? Let’s investigate what not_null (from the Core Guidelines/Guideline Support Library) can do for us.

Intro

In your application, there are probably lots of places where you have to check if a pointer is not null before you process it. How many times do you write similar code:

if(pMyData)
pMyData
->Process();

or:

auto result = pObj ? pObj->Compute():InvalidVal;

or

voidFoo(Object* pObj)
{
if(!pObj)
return;

// Do stuff...
}

What are the problems with the code?

  • It’s error-prone: you might forget about if statements and then you might end up with AV (Memory Access Violation), or some other strange errors.
  • Code duplication
  • Error handling might be on a wrong level. Some functions must accept the null object, but some should depend on the caller to do the checks.
  • Performance hit. One additional check might not be a huge deal, but in some projects, I see hundreds or more of such tests.

What if we could forget about most of those safety checks and just be sure the pointer is always valid? How can we enforce such contract?

As you know, writing a simple comment, like "this argument cannot be null" won’t do the job :)

There’s a simple solution suggested in Core Guidelines:

I.12: Declare a pointer that must not be null as not_null.

So what’s that not_null type? How can it help us?

The article was inspired mostly by Kate Gregory’s original article: Using the not_null Template for Pointers That Must Never Be Nul. Moreover, Kate’s done a great course about core guidelines, where she also experimented with not_null. Check it here: First Look: C++ Core Guidelines and the Guideline Support Library @Pluralsight.

The basics

not_null is a class that can wrap a pointer (or a smart pointer) and guarantees that it will hold only not null values.

The helper class can be found in the Guideline Support Library (GSL, not GLS :))

We can use Microsoft’s implementation:

github.com/Microsoft/GSL/include/gsl/gsl

//
// not_null
//
// Restricts a pointer or smart pointer to only hold non-null values.

(Strangely the class itself is located not in a separate header but in the core header for GSL, so you cannot include only that class without including all other stuff. There’s a reported issue that might solve that problem: #issue 502).

The basic idea is that you can write:

not_null<int*> pIntPtr =nullptr;

And you’ll get a compile-time error as it’s not possible to assign nullptr to the pointer. When you have such pointer, you can be sure it’s valid and can be accessed.

For a function:

voidFoo(not_null<Object*> pObj)
{
// Do stuff...
}

Inside Foo you are guaranteed to have a valid pointer, and the additional checks might be removed.

That’s some basic theory, and now let’s consider a few more examples.

I divided examples into two sections: compile time and runtime. While it would be cool to handle nullptr at compile time only, we won’t get away with issues happening at runtime.

Compile time

The wrapper class won’t allow to construct a not_null object from nullptr, nor it allows to assign null. That’s useful in several situations:

  • When you have not null pointer and want to clear it:
not_null<int*> pInt =newint(10);
// ...
delete pInt;
pInt
=nullptr;// error!

In the above case you’ll get:

error C2280: 
'not_null<int *> &not_null<int *>::operator =(nullptr_t)':
attempting to reference a deleted function

I really advise not to use raw new/delete (my code is only for a demonstration!). Still, not_null gives here an strong hint: “don’t mess with the pointer!”. Such use case is also a topic of the ownership of such pointer. Since we have only a raw pointer (just wrapped with not_null), we can only observe it and not change the pointer itself. Of course, the code will compile when you only delete the pointer and don’t clear it. But the consequences of such approach might be dangerous.

  • When you want to pass null to a function requiring a not null input parameter.

Violation of a contract!

voidRunApp(gsl::not_null<App*> pApp){}

RunApp(nullptr);// error!

You’d get the following:

function "gsl::not_null<T>::not_null(std::nullptr_t) [with T=App *]" cannot be referenced -- it is a deleted function

In other words, you cannot invoke such function, as there’s no option to create such param from nullptr. With marking input arguments with not_null, you get a stronger guarantee. Much better than just a comment :)

  • Another reason to initialise when declaring a pointer variable.

While you can always initialize a pointer variable to nullptr, maybe it’s better just to init it properly (with some real address/value/object) ?

Sometimes it will force you to rethink the code and move the variable to be declared later in the code.

int* pInt =nullptr;
// ...
pInt
=ComputeIntPtr();
if(pInt){
// ...
}

Write:

// ...
not_null
<int*> pInt =CompueInt();
// ...

You can play with the code below. Uncomment the code and see what errors you'll get...

Compile time is relatively easy. The compiler will reject the code, and we have just to redesign/fix it. But what about runtime?

Runtime

Unfortunately, the compiler cannot predict when a pointer becomes null. It might happen for various reasons. So how to get away with the if (pPtr) { } checks?

The expectations

For example:

voidRunApp(not_null<App*> pApp);

App* pFakePtr =nullptr;
RunApp(pFakePtr);

By default we’ll get (Under VS 2017, Windows):

Error

Under that condition the wrapper class can do the following:

  1. Terminate app
  2. Throw an exception
  3. Do nothing

How to control

You can control the behaviour using a proper #define.

See gsl_assert file: github.com/Microsoft/GSL/include/gsl/gsl_assert.

// 1. GSL_TERMINATE_ON_CONTRACT_VIOLATION: 
// std::terminate will be called (default)
// 2. GSL_THROW_ON_CONTRACT_VIOLATION:
// a gsl::fail_fast exception will be thrown
// 3. GSL_UNENFORCED_ON_CONTRACT_VIOLATION:
// nothing happens

I probably prefer to use GSL_THROW_ON_CONTRACT_VIOLATION and that way we can use exceptions to check the null state.

Code rewrite

Let’s look at the following example. When we have only a single pointer param it’s simple anyway, but what if we have more:

So this (2 params):

voidTestApp(App* pApp,TestParams* pParams)
{
if(pApp && pParams)
{
// ...
}
else
ReportError("null input params");
}

can become:

voidTestApp(not_null<App*> pApp), not_null<TestParams*> pParams)
{
// input pointers are valid
}

But now, all of the checks need to go to the caller:

// using
// #define GSL_THROW_ON_CONTRACT_VIOLATION

auto myApp = std::make_unique<App>("Poker");
auto myParams = std::make_unique<TestParams>();

try
{
TestApp(myApp.get(), myParams.get());
RunApp(myApp.get());
}
catch(std::exception& e)
{
std
::cout << e.what()<<"\n";
ReportError("null input params");
}

Is this better?

  • Might be, as we can handle nullptr pointer in only one place, shared for several ‘child’ functions.
  • We can move the checks up and up in the code, and in theory have only one test for null pointers.

You can play with the code below:

Issues

  • Smart pointers? The type is prepared to be used with smart pointers, but when I tried to use it, it looked strange. For now, I am not convinced. Although, the ‘ownership’ of a pointer and null state seems to be orthogonal.
  • Using with Spans
  • Converting constructors
  • Any difference between reference_wrapper? In C++ we have references that were designed not to hold null values, there’s also a reference_wrapper class that are copyable and assignable. So cannot we just use ref wrapper instead of not_null?

Summary

Should we immediately use not_null everywhere in our code?
The answer is not that obvious.

For sure, I am waiting to see such class in the Standard Library, not just in GSL. When it’s included in STL, it would be perceived as a solid standardized helper to our code. I haven’t seen any papers on that, however… maybe you know something about it?

Still, I believe it can help in many places. It won’t do the magic on its own, but at least it forces us to rethink the design. Functions might become smaller (as they won’t have to check for nulls), but on the other hand, the caller might require being updated.

It’s definitely worth a try, so I plan to write more code with not_null.

Call to action:

  • Play with not_null for some time. Share your feedback.

Expressive C++ Coding Challenge Results

$
0
0

Expressive C++17 challenge Results

Three weeks ago with Jonathan from Fluent C++, we announced a coding challenge: link here.

Let’s meet the winner and discuss some of the best solutions

(Our choice is quite surprising! See why :))

First of all, I’d like to thank you all for the submissions to the challenge. The task was ambitious! The final solution wasn’t just a few lines of code, but more than 100… on the average around 200 LOC… sometimes even more. To write such app for sure, you had to spend a few good hours. We appreciate your time and effort!

We got 11 entries.

If you’re one of the participants, you should be proud of yourself! You’ve learnt some C++17 and wrote a working app!
Congratulations!

The rules

Just to remind:

The task proposed in the challenge is to write a command line tool that takes in a CSV file, overwrites all the data of a given column by a given value, and outputs the results into a new CSV file.

In other words, you had to code a command line tool that transforms an input CSV file with some rules and then saves it as a new file.

Desired effect:

Replace fields under the “City” label, with “London”. We want all the people from the input file to be now located in London.

Expressive C++ 17 coding challenge sample

Not super simple, as it requires several elements like:

  • Reading and writing to a text file
  • Parsing CSV header
  • Parsing CSV lines
  • Searching for a selected column
  • Replacing the text
  • Error handling
  • Reading from command line arguments

Originally it was motivated by a simple PowerShell script:

Import-Csv.\input.csv |ForEach-Object{
$_
."City"='London'
$_
}|Export-Csv.\output.csv -NoTypeInformation

Unfortunately it’s not that simple in C++ :D A bit more LOC needed :)

The Winner

We selected:

Fernando B. Giannasi

Here’s his solution: link to code at Coliru

And here’s a surprising fact about Fernando:

He’s not a professional programmer :)

I work as an Intensive Care and Emergency Physician (a.k.a intensivist) in my cities ICU’s.

And his story:

I’m a Linux enthusiast since the 90’s, which in an almost natural way led me to be interested in programming.
I have a strong background on shell script and Python, which I have also used for data analysis.
The first contact I had with (mostly) C and C++ was before college, about 15 years ago, and it did not suit my needs since I often found myself struggling with awkward syntax and details/constraints from the language rather than the real problem I was trying to solve. So with Python, I went some years after…

But a few years ago I was working with Raspberry-Pi projects, and I felt the lack of performance of my approach using Python and Bash scripts, and I decided to give C++ another try.
Man, what a different language!!
All the algorithms I liked were there on the STL… And the containers, the performance, RAII, everything feels so natural that I never turned back.

Wow! So there’s hope in C++, with the modern features and coding style :) I wish more and more people will perceive C++ that way.

The winner’s solution

Let’s dive into the code:

If we go from main() into details we get the following picture:

The main() core part:

try
{
if(argc !=5){throw runtime_error("Bad arguments");}

auto[in_file, out_file]= get_file_handlers(argv[1], argv[4]);

string_view new_value
= argv[3];
auto target_index = get_target_column(in_file, argv[2],',');
if(target_index){
do_work
(in_file, out_file,*target_index, new_value,',');
}
else{
throw runtime_error("Column name doesn’t exist in the input file");
}
}
  • The code reads the input data from argv.
  • Opens the files, input and output
  • Finds the target column (the return value is optional<int>)
  • If the column index was found we get into the transform code that does all of the replacement.
  • If anything wrong happens we’ll get an exception
  • There’s a structured binding used to store streams of the input and output.

get_target_column:

the header:

[[nodiscard]] optional<int> get_target_column(ifstream& input,
const string_view& label,
constchar delimiter)

and the core part:

auto tokens = split_string(first_line, delimiter);

if(auto it = find(begin(tokens), end(tokens), label);
it
== tokens.end()){
return{};
}
else{
return distance(begin(tokens), it);
}
  • it reads the first line of the input file and then splits the string into tokens (using a delimiter)
  • returns an index if found something
  • [[nodiscard]] will remind you actually to use the return value somewhere. See my post about C++17 attribs.
  • The code is super clean and so easy to read.

And below the code that splits the string (line):

[[nodiscard]]auto split_string(const string_view& input,
constchar delimiter)
{
stringstream ss
{input.data()};
vector<string> result;

for(string buffer;
getline
(ss, buffer, delimiter);)
{result.push_back(move(buffer));}

return result;
}
  • I don’t have to add any comments, very easy to read and clean.

And here’s the core part of the transformation:

string buffer;

getline
(input, buffer);// for the header line
output
<< buffer << endl;

while(getline(input, buffer)){
auto tokens = split_string(buffer, delimiter);
tokens
[target_index]= new_value.data();

for(auto& i: tokens){
output
<< i;
output
<<(i == tokens.back()?'\n':delimiter);
}
}

Again: clean and expressive.

Here’s what motivated Fernando:

… I think that a simple problem screamingly demands a simple solution, since correct of course.

So I tried to write a solution that my wife or my son could easily understand…

I mean, C++ has so many nice features, but as with any other tool, using all of them to solve a simple problem didn’t feel right…

The code is a perfect example of modern C++. And this is why Jonathan and me chose him as the winner.

Worth mentioning

With so many good entries, it was hard for us to pick the winner. Moreover, there are many possible solutions and approaches. You might also want to look at the following examples:

  • In this solution the author usedline_iterator and tag_iterator. With those core tools, he was able to traverse the file efficiently. Also, such approach looks very scalable and can be easily adapted for other requirements.
    • This is an advanced code, so we were really impressed with the quality and effort to write such beauty.
  • In my C++17 articles, I forgot to mention, that std::iterator is now deprecated. I am glad that all of the solutions where an iterator was proposed remembered about this spec change.
  • Surprisingly, a lot of people used std::experimental::ostream_joiner from Library Fundamentals V2. This is not yet in the standard, as I know, but looks really good.
    • Used in solution like: William Killian
    • see the cppreference link.
    • Basically it’s an ‘optimized’ version of ostream_iterator. It usually makes only one write to the output for a range of values.

Summary

Once again thank you for the code, it was a great experience to review them. I see how much I need to learn to write such code!

To end this post, I’d like to mention another quote by the winner:

If C++ has the reputation for being too much “expert friendly”, it do not need to be that way, specially if you keep simple things simple.

Isn’t that true? :)


Better code understanding with Sourcetrail

$
0
0

Sourcetrail, review

Do you write code 100% of your job time?

I guess the answer is no. We can skip all the management part, meetings, coffee, youtube, cats… etc… but still, even if you’re next to your keyboard it’s not all the time you write. So what else do you do?

A short answer: you’re probably figuring out what to write and where to add new features (and what to fix)… so you’re mostly reading and trying to understand the code.

There are tools to help you with better code understanding which are not just text editors. One of such application is Sourcetrail, let’s see what can it do for us.

Bonus!, read further to see details of our new giveaway :)

Promo note: This article is sponsored by Coati Software. Written by me.

Intro

Time Spent
New Code2…10%
Modifying Existing Code15…30%
Understanding Code60…75%

The numbers come from link and link.

We can argue about the exact numbers if writing code is only 2% or 5% or maybe more. If code understanding is 50% or 75%. But I completely agree that it’s X times more required to understand and read code than writing new parts.

Think about a new feature you add to your project. How do you approach such task?

For me it’s usually understanding the spec (or writing it), later, assuming I know most of the requirements I can start thinking where to put a new code.

I am happy when I’m familiar with the area of the project where the new feature will be included. Still, even in a ‘known’ part of the system, I learn something new every time. So usually, I end up analysing the existing code.

Or imagine you’re thrown into an entirely new project. You sit in front of a huge code base… how to start and dig your way through?

What can we use to understand the code? Only a text editor? Maybe we can visualize the project?

The Tools

What options do we have?

Of course, there’s your favourite IDE’s text editor. Assuming you’re not just using a Notepad, your editor will contain a few advanced features:

Basic tools

  • Search - and a lot of its variations, like search in files, searching any symbols, etc.
  • Efficient navigation, moving between files, last visited locations, symbols.
  • Going to the definition/declaration of a method/class/name.
  • Finding (all) references of a symbol/name.
  • Listing all methods/types in a file/project.
  • And of course syntax colouring, seeing everything in black&white would be quite a nightmare.

Recently, it’s quite common to include an extended version of a scrollbar (Code Map, Mini-Map). This is a little tool that allows to look at a particular file from a larger distance and see its layout or places with changes/errors.

Ok… those are some essential elements? What other tools can we use?

With Visual Studio and some of its extensions (like Visual Assist), you can also easily navigate between hierarchies of classes. So you can know what’s a base class, the chain of base classes, or what are the derived types.

Also, it’s great if you can navigate to related symbols: if you have a list of member variables, methods, constructors, etc.
Such tool can significantly reduce the time needed to scan the source code where a type is declared.

Another useful tool is Call Hierarchy: to know where your function is called. It’s available in all Visual Studio versions: see a link here.

OK, but what else can we use?

Graphs

Graphs!

It would be great to see the code as a graph of objects and their relations… something like a dynamic UML, where you can see the whole picture or some part of it.

And we have a few existing tools that can help us (and work with C++):

  • CppDepend - CppDepend offers a wide range of features. It is often described as a Swiss Army Knife for C and C++ developers. Offers Code analysis, Code Visualisation, Code Quality Metrics and much more.
  • SciTools Understand - very advanced. Understand is an IDE designed from the ground up to help you “Understand” your code. It can be used for maintaining existing code or writing new code from scratch.
  • Source Insight - a powerful project-oriented programming editor and code browser, with built-in analysis for large C/C++, C#, Objective-C++, Java programs, as well as other languages. Not only is Source Insight a great program editor, but it also can display reference trees, class inheritance diagrams, and call trees. (239$ per licence.)
  • Code Map from Visual Studio Enterprise.
  • Doxygen and other documenting tools that will also draw a ‘map’ of your code.
  • And: the hero of this article: Sourcetrail - a powerful tool for code visualization, multiplatform and independent from your IDE.

BTW:
If you like to have a look at this discussion at software engineering @Stack Exchange: How To Visualize Code? or C/C++ source code visualization? - Stack Overflow.

Sourcetrail

What can Sourcetrail do for us?

First of all, it’s a tool that doesn’t try to replace your text editor. Its objective is to assist with code exploration by creating dynamic graphs that show your project from a different perspective.

When you work with code, you build a mental model of the relations between types. Sourcetrail helps with the task by drawing all the UML-like pictures for you.

Sourcetrail is built upon the three core concepts:

  • Code - the code around a selected type/name is shown, and at any time you can just read it as with other text editors.
  • Graph - interactive and dynamic graph built from the selected symbol name. It can centre around a class, file, macro, function… or even a template parameter.
  • Search and Navigation - a powerful search is required to find and navigate to a symbol quickly. Also, comes with autocompletion.

See below a default layout of the windows:

Sourcetrail Default View

Of course, the trickiest part is the Graph.

But first, a short story behind the team and the product.

About the company, Coati Software

Team Coati.

Image taken from: their blog post.

Let’s first introduce the company behind Sourcetrail; the founders can share a fascinating story of why it all started.

Briefly, the tool was created out of frustration from working with large code bases (when Eberhard was working as an intern at Google). Reading only text is not the most efficient way of understanding a new code, so after a couple of experiments, the team started implementation of the project.

The full version of the story can be found on the following blog post:
Why working on Chrome made me develop a tool for reading source code.

The company are based in Salzburg/Austria.

Recently, at CppCon2017 one of the founders of Sourcetrail, gave a little talk/demo. Just watch that short 4-minute talk:

Ok, but let’s not move to the tool!

Sourcetrail

Some basic details:

Sourcetrail works offline, with all popular operating systems: Windows, Linux and MacOS.

Sourcetrail was in Beta since spring 2016 and is available as stable release since June 2017. Now, in Nov we have the version 2017.4.

What’s cool is that since a few days (announced 25th Oct) Sourcetrail is free for non-commercial use. So you can just download it and play! See more in this recent blog post: Sourcetrail 2017.4 – Sourcetrail Developer Blog.

It supports C++ and Java code bases. If you’re using CMake, it’s very easy to setup the compilation database. For Visual Studio, there’s a separate plugin that will do the hard work.

The team is very responsive to user feedback and open to feature suggestions. So have a look at this open bug tracker: github.com/SourcetrailBugTracker/issues. Suggest your ideas if you like!

Experimenting with the tool

For my experiments, I’ve selected a project named Celero (v 2.1). It’s a microbenchmarking library (I wrote about it in this post).

It’s a project of a decent size. So it should be relatively quick to analyze and still see the tool operating on something more significant than a “hello world” application.

I wanted to go through the whole process of the setup and launching the tool. On Sourcetrail site there are example projects if you want just a brief look: sourcetrail/downloads - like clang source code. And in the tool installation image there some tutorials included as well.

Loading a project

Before we can see some neat looking diagrams, we need to process the code.

Sourcetrail under the hood uses Clang tooling, so in other words, your code needs to be compiled under Clang. With the generated abstract syntax tree Sourcetrail can extract all of the details and build desired code models.

It might be quite a hard task to setup everything, but Sourcetrail provides a lot of help here. In case of Visual Studio, there’s attached plugin that can help us: Sourcetrail Extension for Visual Studio.

Indexing

After the project is setup correctly, you can load it into the app, and it will ask about indexing.

This process can take some time, depending on the project size, but usually, it’s done once. Later cached data is used, so only changed files will be reparsed.

I am not sure about the exact details, but although your code is compiled with clang, not everything is required to be fully compiled. Even if you get some errors, the file will be indexed. Only fatal errors prevent from being in the index.

BTW: I’ve also tried this on my big project, with 2 mln lines of code. I got many compilation errors, but only a few fatal in non-important files. Anyway, I could still browse the code and Sourcetrail worked fine with such a vast project.

Browsing

Once the previous steps are completed, we can start looking at the diagrams.

Here’s what I get when I load the Celero project:

Default view for a project in Sourcetrail

The above diagram is your home place. If you want to reset the chart, you can just click on the “Home” icon on the Search&Navigation toolbar.

Home button, Sourcetrail

Or you can also type “overview” (or some part of it) in the Search box.

Let’s now try to understand some code from Celero.

For example, after clicking randomly at nodes and classes, I’ve seen a lot of pimpl idiom used. There’s even a separate class for it:

When I click on the node class I get the following view:
Looking at a class, Sourcetrail

What’s important here is that in a microsecond I get so much valuable information:

  • On the right hand there’s code of the class so that I can read it “normally”. For example, there are a few constructors and maybe it would great to update it to variadic templates :)
  • On the left, we see all of the relations:
    • member variables
    • template parameters
    • template specializations
    • referenced symbols

I mentioned that I clicked randomly on a node, but if you know what you’re looking for you can just type it, and a fuzzy-matching search box will quickly find it.

Sourcetrail works fine with nested types like Pimpl nested in the Archive class:

Nested types, Sourcetrail

  • Blue nodes represent variables and fields
  • Yellow is for functions and methods

For example, when I click on filename I’ll see where the field is being used:

Show where a field is used, Sourcetrail

I am impressed with such view! Blue lines on the diagram represent where a field is being used, plus we get a ‘snippet’ view in the source editor. That way I can immediately read the code in the relevant places.

In this view there’s “override” edge presented:

override edge for virtual functions, Sourcetrail

You can see where are all of the implementations of Factory::Create methods.

Also, I got one cool diagram. Have a look:

String references, Sourcetrail

The picture above shows all the places where std::string is referenced.

  • yellow are all of the functions where string is used (also as an input params)
  • grey are the classes
  • red lines represent places where string is used as a template parameter

Possibly, it’s not the most useful diagram, but it’s fun to see. Maybe it’s another good point of using such software: you can just play with the code/architecture and have fun at the same time.

In this particular project, there is not much inheritance, and the class structure is pretty flat. But of course, Sourcetrail lets you see base classes and derived types. You can smoothly go up or down in a class family.

For browsing functions Sourcetrail presents call graphs: For example here’s one for function called Run() :

You can see both the caller side and the callee.

As you can see we can go over and over and browse more code. Let’s stop for now as I hope that little trip gave you a basic background behind Sourcetrail. There are so much more we can do.

So maybe you can just download Sourcetrail and see it for yourself?

Summary

Strong points:

  • A powerful search
  • Nice looking diagrams/graphs… I mean really awesome looking!
  • Designed for C++/Java, but I think it will be possible to get support for other languages.
  • The initial indexing process might take a long time, but you have control of how many threads are invoked, you can even stop it and use only part of the information. Of course, there’s cache so only changed files have to be refreshed/reparsed.
    • I could for example run indexing in the background (by assigning only a few threads for the work), and still be able to work on my tasks so that Sourcetrail can finish its part.
  • Ready to use plugins (like for Visual Studio) to help you with importing projects into Sourcetrail.
  • Multiplatform: so works on Windows, Linux and MacOS.
  • Lightweight: it might fill a gap between no software for visualisation vs super advanced (and expensive) tools (like SciTools or SonarQube)
  • Useful tool for playing with templates - you can see specializations, parameters, etc.
  • Active development, new features every three months.

Plus:
It’s free for non-commercial uses :)

Weak points:

  • (general “problem” for such extra apps) Need to switch between tools. Although there’s an IDE helper that allows changing a bit faster, maybe it would be
    better to have the view entirely inside an IDE? Like a separate window next to your cpp file?
    • If switching is a “heavy” operation, then developers might be discouraged to run the tool often.
  • Sometimes you might get a lot of clang errors, mainly if you use other compilers for your project (like Visual
    Studio). Still, even with errors, the symbol from the file appears in the graphs.
    • Track this issue to get more info about error vs fatal differences.

To be honest, I cannot find any more serious issues. I’m exploring the tool, and overall I am impressed. It works very well; the setup is easy to do, there’s a lot of help, beautiful and dynamic diagrams (even with smooth animations), under active development… what else would I want? :)

BTW: If you want to get the full commercial licence look at many discount options (see Sourcetrail Pricing): like 50% for freelancers and start-ups.

Or you can also take part in the giveaway to get a full licence, see below :)

Giveaway

Together with Coati Software, we want to invite you to a new giveaway. You can get a commercial licence for Sourcetrail!

Enter your details in the tool below and comment below answering one of the following topics:

  • What do you use to visualize code? any advanced tools or just a text editor?
  • Have you played with Source Trail? Please share your opinion. (you can download it for free and test).

(please write more than just one sentence/word)

Sourcetrail Giveaway

The giveaway ends in two weeks (by Monday 13th Nov, 7:59 PL Time), and the winners will be notified on 13th November.

Enforcing code contracts with [[nodiscard]]

$
0
0

nodiscard attribute C++17

For my article series about C++17 features, I’ve made a separate entry about new attributes. At first sight, I thought that [[nodiscard]] is just another simple and a rarely used thing. But later I thought… hmmm… maybe it might be valuable?

One reason is that [[nodiscard]] might be handy when enforcing code contracts. That way you won’t miss an important return value.

Let’s look at a few examples.

Intro

[[nodiscard]], as mentioned in my article: C++17 in detail: Attributes, is used to mark the return value of functions:

[[nodiscard]]intCompute();

When you call such function and don’t assign the result:

voidFoo(){
Compute();
}

You should get the following (or a similar) warning:

warning: ignoring return value of 'int Compute()',
declared
with attribute nodiscard

We can go further and not just mark the return value, but a whole type:

[[nodiscard]]structSuperImportantType{}
SuperImportantTypeCalcSuperImportant();
SuperImportantTypeOtherFoo();
SuperImportantTypeCalculate();

and you’ll get a warning whenever you call any function that returns SuperImportantType.

In other words, you can enforce the code contract for a function, so that the caller won’t skip the returned value. Sometimes such omission might cause you a bug, so using [[nodiscard]] will improve code safety.

You can play with some code below:

One note: You'll get an warning, but usually it's a good practice to enable "treat warnings as errors" when building the code. /WX in MSVC or -Werror in GCC.

I hope you get the basic idea. But the above stuff is just some generic FooBar code. Are there any useful cases?

Where can it be used?

Attributes are a standardized way of annotating the code. They are optional, but might the compiler to optimize code, detect possible errors or just be more specific about the intentions.

Here are a few places where [[nodiscard]] can be potentially handy:

Errors

One, crucial use case are error codes.

How many times have you forgotten to check a returned error code from a function? (Crucial if you don’t rely on exceptions).

Here’s some code:

enumclass[[nodiscard]]ErrorCode{
OK
,
Fatal,
System,
FileIssue
};

And if we have several functions:

ErrorCodeOpenFile(std::string_view fileName);
ErrorCodeSendEmail(std::string_view sendto,
std
::string_view text);
ErrorCodeSystemCall(std::string_view text);

Now every time you’d like to call such functions you’re “forced” to check the return value. I often see code where a developer checks only some return error codes. That creates inconsistencies and can lead to some severe runtime errors.

You think your method is doing fine (because N (of M) called functions returned OK), but something still is failing. You check it with the debugger, and you notice that Y function returns FAIL and you haven’t checked it.

Should you mark the error type or maybe some essential functions only?

For error codes that are visible through the whole application that might be the right thing to go. Of course when your function returns just bool then you can only mark the function, and not the type (or you can create a typedef/alias and then mark it with [[nodiscard]]).

Factories / Handles

Another important type of functions where [[nodiscard]] adds a value are “factories”.

Every time you call “make/create/build” you don’t want to skip the returned value. Maybe that’s a very obvious thing, but there’s a possibility (especially when doing some refactoring), to forget, or comment out.

[[nodiscard]]FooMakeFoo();

So what about new from the Standard Library? It’s also a ‘factory’ … isn’t it? Read further, please :)

When returning non-trivial types?

What about such code:

std::vector<std::string>GenerateNames();

The returned type seems to be heavy, so usually, it means that you have to use it later. On the other hand, even int might be heavy regarding semantics of the given problem.

No side effects

The code in the previous section is also an example of a function with no side effects. In that case, we need to do something with the returned value. Otherwise, the function call can be removed/optimized from the code.

Hmmm… so maybe we should use [[nodiscard]]

Everywhere?!

Ok, let’s not be that crazy… using returned value from a function is usually useful and developers do assign to a variable, so we cannot assume that all the cases should be marked [[nodiscard]].

There’s a paper that might be a “guide” [P0600R0 - [[nodiscard]] in the Library](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0600r0.pdf)

I think it didn’t make into C++17, but it suggests the following:

We suggest a conservative approach:
It should be added where:

  • For existing API’s
    • not using the return value always is a “huge mistake” (e.g. always resulting in resource leak)
    • not using the
      return value is a source of trouble and easily can happen (not obvious
      that something is wrong)
  • For new API’s (not been in the C++ standard yet)
    • not using the return value is usually an error.

Here are a few examples where the new attribute should be added:

  • malloc()/new/allocate - expensive call, usually not using the return value is a resource leak
  • std::async() - not using the return value makes the call synchronous, which might be hard to detect.

On the other hand such function as top() is questionable, as “not very useful, but no danger and such code might exist”

So for now, I wouldn’t add [[nodiscard]] in all places of your code but focus on the critical places. Possibly, as mentioned before, error codes and factories are a good place to start.

Moreover, it’s useful when you want to discourage using some functions: :) have a look below:

How to discourage using printf :)

As printf is not the safest method of printing text, and there’s a idea to move to a safer approach like iostreams.

So maybe we can discourage printf?

I got that idea from Björn Fahller @Twitter:

So we could mark it and then every time you’d like to use this code you’d have to write:

if(printf(...)<0)
error
();

// or at least:
[[maybe_unused]]auto ret = printf(...);

Not nice… right? :)

Ok, but let’s not be that evil!

We all know printf is the core tool for debugging! :)

How to ignore [[nodiscard]]

With [[nodiscard]] you should assign the return value to something, and you should also use this variable later. If you forget, you’ll get another warning “unused value”.

To suppress the warning you can use another attribute from C++17: [[maybe_unused]]:

[[nodiscard]]intCompute();
[[maybe_unused]]auto t =Compute();

Still, this is a hack to me, and usually in that case it’s better to rethink the design a bit :)

Before C++17

As I see, most of the attributes that went into the standardized [[attrib]] comes from compiler extensions.

For example, in GCC/Clang, you can use

__attribute__((warn_unused_result))

in MSVC:

_Check_return_ - see more in MSDN: Annotating Function Behavior.

Summary

To be honest, I haven’t used attributes much. Also, I haven’t seen a lot of code that has attributes applied. It’s probably natural because previously they were available only as an extension so used rarely. Now, since C++11 they went into the standard form, there’s a chance to see them more often. We have to learn how to use them efficiently.

To sum up: [[nodiscard]] is an excellent addition to all the important code: public APIs, safety-critical systems, etc. Adding this attribute will at least enforce the code contract, and a compiler will help you detect bugs - at compile time, rather than finding in in the runtime.

For now, Core Guidelines also doesn’t mention anything about [[attribs]], but I hope to see some essential use cases described someday.

  • Have you used nodiscard (in C++17 way or as an extension) before?
  • What are your suggestions here?
  • Would you mark all possible functions? :)

References

code::dive 2017 conference report

$
0
0

Code::Dive 2017 report

This year I had a chance to visit Wroclaw for the 4th edition of Code Dive! Two days of a great programming conference!

Briefly: many of topics related to C++, two days, 40 presentations, lots of people and a beautiful city. What more do you need? :)

Continue below to read my report from the event.

Intro

The conference took place in “Kino Nowe Horyzonty”, Wroclaw on 14th and 15th November (Tuesday, Wednesday).

The venue was a cinema in the centre of the city. Watching a talk was a pleasurable experience, as you got a comfortable seat and no one would cover the view in front.

I was in the first edition of the event, in 2014: see my report here. And at the end of that post I wrote:

Great conference and I would love to attend next year. I hope Nokia (or maybe others sponsors) will decide to host this event in 2015 as well.

And fortunately, Nokia decided to continue doing the conference. Many thanks!. We don’t have many (or even any!) C++ conferences in Poland, so Code::Dive serves an important role here.

Here’s the main site where you can check the details:

code::dive

Their youtube channel:

code::dive conference - YouTube

And Twitter:

code::dive (@code_dive_pl) | Twitter

Please track the youtube channel. Hopefully, in the next few days, we’ll see the recorded versions of the talks. At the moment you can just watch saved live streams, but only from one of the fourth tracks.

code::dive 2017 conference - day 1 - YouTube

2016 edition:

http://codedive.pl/index/year2016 (links to slides, videos, etc)

Day 1 presentations

John Lakos: Value semantics: It ain’t about the syntax!

To be honest, I’ve seen only a part of this presentation… on a live stream while travelling via bus to Wroclaw :)

You can see it also through the youtube link: code::dive conference day 1, but the same talk can be seen in many other places. For example:

CppCon 2015: John Lakos “Value Semantics: It ain’t about the syntax!, Part I” - YouTube and

CppCon 2015: John Lakos “Value Semantics: It ain’t about the syntax!, Part II” - YouTube

While I’ve seen only the first 40 minutes, it’s a good thing for me because it’s a really “heavy” talk. It’s probably a good idea to watch it a few times, with some breaks.

Just a few words about John: he’s the author of Large-Scale C++ Software Design - a book from 1996, but still very valid! He works for Bloomberg in New York, and he’s also an active member of C++ Committee.

The core concepts of the talk:

  • The presentation talks about value types and various categories of them. Probably we all feel what a value is, but John went further into real Information Theory and Mathematics to show important aspects.
  • C++ types/objects are only a representation of mathematical entities. For example type int represents only an approximation of the mathematical integer type.
  • Salient attributes - attributes of a type T that contribute to its value. If all salient attributes have the same value, then we can say that two objects of type T have the same value. We don’t care about the representation, internal implementation here.
  • For example in std::vector we care about values of individual objects in the container and the size of the container. But capacity is something internal.
  • Why unique values are important: because we might want to transfer the same value to other processes and still be able to understand and compare it. For example: store a Date record in a database.

What’s more John mentioned that he has finished working on the text for his upcoming (and delayed) book: Large-Scale C++ Volume I: Process and Architecture. It supposed to be released in 2014 as far as I remember, but it was constantly pushed. But at least there’s hope for Spring 2018 :)

Alex Crichton: Concurrency in Rust

I got at this talk by accidence! :)

I was late and wanted to go to Andrzej Krzemieński talk about undefined behaviour. But the room was full, and I couldn’t enter. So I decided to see what’s Rust all about!

Alex Crichton, the presenter, https://github.com/alexcrichton, is a Staff Research Engineer at Mozilla and has been working on the Rust programming language for 5 years.

Sadly, the Alex’s another talk - “Introduction to Rust” was scheduled for the second day. So all in all, it was a too advanced and complicated topic for me to understand - as I am not experienced with the language.

Maybe I didn’t get all of the things, but still I noted a few important aspects:

  • Rust might be designed as a competitor to C++, and it’s also native language. Still no-one can tell me that it’s much easier than C++
  • I like borrowing, ownership and lifetime concepts; this guarantees safety. The disadvantage: it sounds complicated! We have something similar in C++, but I feel in Rust it’s more ‘explicit’, with more techniques to use.

Mark Isaacson: Exploring C++17 and Beyond

Mark Isaacson is a Software Engineer at Facebook, where he works on improving the developer experience for all C++ programmers at Facebook. He’s also the author of:

Modern Maintainable Code Blog

The presentation can also be found here:

http://maintainablecode.logdown.com/posts/745037-tech-talk-exploring-c-17

Some notes:

  • Mark went quickly through the list of new features but stopped on three things:
    • string_view
    • operator dot (future thing, might even not go into C++20)
    • constexpr if
  • With the first topic - string_view he showed a few examples where might it help. For example it’s good when replacing const char* global/static values.
    • But, on the other hand, we need to understand that it’s only a view, we don’t own the memory. So string views should be used with care
  • Operator dot N4173 - a paper from 2014, might be outdated. An interesting thing that could expose the underlying members through only one additional operator. Could be handy for pimpl idiom.
  • constexpr if - I liked the comparison about template metaprogramming. For most of the people, it’s a complete magic. All of crazy things that are needed to write an if (like tag dispatch or SFINAE). With constexpr if we can just write if. So it’s reducing that magic.

Andreas Weis: Howling at the Moon: Lua for C++ Programmers

Andreas works in BMW, and he’s also a co-organizer of C++ Munich Group.

Shorter version of the talk (we had 60 minutes)

CppCon 2017: Andreas Weis “Howling at the Moon: Lua for C++ Programmers” - YouTube

Slides for the talk

My notes:

  • Lua (@wiki) is used mostly for gamedev, but other apps might also use it. For example Adobe Lightroom, some Arduino? boards.
  • Designed at university in Brasil
  • It’s designed as embeddable language. So it’s much lighter than other languages that could be used as a separate language (for example like Python, javascript)
  • Very small and relatively fast
  • The talk describer the basics of the language and how can it be integrated into C++ app
  • Andreas presented a few examples where C++17 shines:

for example: fold expressions

// Pushing values on the stack, `push` for each type
void push(lua_State* l, lua_Number n){
lua_pushnumber
(l, n);
}
void push(lua_State* l,charconst* s){
lua_pushstring
(l, str);
}

// fold:
template<typename...Ts>
void pushargs(lua_State* l,Ts... args){
( push(l, args),...);
}

Or using std::variant to represent all 8 possible types that Lua support.

A good example to read and understand how modern C++ might help!

Łukasz Langa: Thinking in coroutines

Another mistake?

Hmm… I didn’t read the notes/description under the talk, and I though it’s about C++ coroutines… but it was Python! :D

For a while, I considered leaving the room, but the presentation was started very light, and with energy, so I decided to stay.

Co routines are a generic concept, so maybe that knowledge would help me in C++ as well?

But to be short, it all looks nice, and we can do a lot of powerful things using co-routines. Still it requires to shift thinking, so might be hard at fist.

Day 2 presentations

John Lakos: Local (“arena”) memory allocator

For now you can watch this talk:

Local (arena) Memory Allocators - John Lakos [ACCU 2017] - YouTube

Notes:

  • We have local, global and general/special purpose allocators.
  • By using proper types we might get an order of magnitude in performance!
  • In C++17 we get polymorphic allocators
  • I still need to dig further and understand what’s that all about and how can we use it
  • John presented various benchmark results and commented why something might be faster/slower.
  • Huge potential, but not all devs/projects care about it

Eric Niebler: Introducing the Ranges TS

Eric Niebler is a senior engineer at Facebook and an active member of the ISO C++ Standardization Committee. He is the principal author of the upcoming Ranges TS and of the range-v3 library on which it is based

http://ericniebler.com/

Ranges TS N4685, Working Draft, C++ Extensions for Ranges will be published in a few days, and I was surprised that this paper is relatively “simple” (although 180 pages :))! We won’t get all that things that we think “Ranges” are: like views, generators.

Still we’ll get the core and crucial parts:

  • background for Concepts (as Ranges are based on Concepts)
  • callable objects
  • The addition of new concepts describing range and view abstractions; that is, objects with a begin iterator and an end sentinel
  • Analogues of the Standard Library algorithms specified in terms of the new concepts.
  • plus some more

So this will 99% go into C++20. Now Eric works on the stuff that is based on that core functionalities. Depending on the speed it might also went into the new standard. Maybe even as STL2?

On this presentation, Eric also showed some other powerful ideas like:

  • Ranges TS with Parallel TS (on GPU!) - using SYCL implementation.
    • Some experiments showed even being faster as handwritten CUDA code!
  • Ranges and coroutines
    • Being async
    • Reactive programming in C++

Mark Isaacson: Developing C++ @ Facebook scale

Mark’s blog post

Slides: PDF

Notes:

  • In a huge code base (like Facebook’s) your commit might break work for hundreds of other developers. How to mitigate it?
  • How flaky tests might affect build/tests results. How to separate such flaky tests
    • updating test runs with more data, like by using folly::symbolizer::installFatalSignalHandler
  • Automatization of code review
    • Use existing tools: like clang format (to avoid coding style wars! :))
    • running ASAN/Sanitizers tools for checking memory safety, undefined behaviour, etc

Good questions we should be asking in a healthy project:

  • How do you prevent code from breaking?
  • How do you define “broken”?
  • How do you know if something broke?
  • How do you figure out why something broke?
  • Who do you talk to when something breaks?

Takeaways

  • Other languages are also hard! So C++ is not the only language that is sometimes complex and hard to learn.
  • A lot of programming aspects (like coroutines, reactive programming, etc) is common to all languages. It’s worth to know the differences, or just be aware that other languages also tried to solve some problems.
  • Automate the code review process!
  • Coroutines are getting very popular, in many languages

After one talk I’ve also heard (from the participants) quite important sentence, it sounded more or less like: “C++17 and beyond is so off the ground”… So basically we can talk about nice and shiny things, but normal C++ coding is so much different. Some companies haven’t even moved to C++11.

What’s more, while travelling back home, I generated around 20 ideas for my new blog posts. I need to sort them out and I plan to start writing the content.

Summary

Code::Dive technologies

While I treat Code::Dive as C++ conference it’s probably not how it’s designed. There are other languages that took great deal of the talks: Go, Rust, Java, Python, AR, IoT… so I might better change my view to “a native programming conference”. Still, lot’s of benefits for me.

I hope to visit Wroclaw next year :)

Have you been at Code::Dive this year?
Share your thoughts about this even in the comments!

Summary of C++17 features

$
0
0

Summary of C++17 features

How do you see the new C++ standard? Is it ok? Great? Meh?

Last week, after a few years of break, I presented my new talk that addressed the above question! It happened at the Cracow C++ Local Group.

Have a look what’s inside this talk.

Intro

Listing all of the features from the new standard might sound simple at first glance. All you have to do is to go through the things alphabetically, mention a few code samples and you’re done :)

For example here’s the picture with such list:

List of C++17 features

Quite a lot… right? :)

So I came up with a categorization, the same as you could read in my C++17 article series:

  1. Fixes and deprecation
  2. Language clarification
  3. Templates
  4. Attributes
  5. Simplification
  6. Library changes - Filesystem
  7. Library changes - Parallel STL
  8. Library changes - Utils

I am not sure if that’s the best order, but at least it groups things together.

The talk

The talk was presented at :

Summary of C++17 features | C++ User Group Krakow (Kraków, Poland) | Meetup

And here are the slides:

Summary

Ok… so what’s the answer to that C++17 awesomeness question?

In my opinion, it’s a very decent standard.

We got a lot of powerful features (like fold expressions, constexpr if, template argument deduction for class templates, filesystem, parallel STL, …). There’s always a desire to have more, but that couldn’t happen due to the new standardization process. Every three years we’ll get a new version. While C++17 is “smaller” than C++11, it’s shipped faster (3 years) rather than 13 years! So we cannot forget about this.

And another point: how to efficiently learn when the language is changing so fast? :)

5 ways how unique_ptr enhances resource safety in your code

$
0
0

unique_ptr

Modern C++ stresses the use of RAII objects to manage resources. One of the easiest ways is just to start using unique_ptr across your code.

Let’s see how we can leverage this smart pointer type. I’ve come up with 5 (or more?) reasons where unique_ptr shines.

Intro

One of my favourite features of modern C++ is smart pointers. They are maybe not magic bullets that solve all resource management problems. Still, they play a significant role in enforcing safety. By using them, you can avoid memory leaks, access violations errors and be sure the object clean up is done right.

While shared_ptr and weak_ptr are more complex, unique_ptr seems to be a perfect replacement for owning raw pointers. Not to mention is the fact that this pointer type is mostly a compile time “wrapper” and it cost almost nothing in the runtime.

So for today, I’ve selected five… six strong points of unique_ptr. Think where, in your project, could you immediately apply such pointers. Or maybe you have done that already? :)

Let’s start!

0. Just use the stack

I know we’re talking about memory allocations, pointers, etc, etc… but at the beginning, I’d like to make a little remark.

Sometimes using the heap is necessary, for example when your object needs to live longer than the current scope, or when you don’t know the exact size of the object (it needs to be computed in the runtime), or when your object is large.

Still, think about the stack… maybe your object can be put there? Often, I’ve seen that an object is allocated on the heap, while it could be safely placed on the stack.

The stack is faster, safer and just works :)

The default stack size is around 1MB in MSVC (platform specific), that included memory for the call stack, params, etc…. but if your object is not super large and you’re not doing any deep recursions, it should be good enough.

Also remember that containers, like vector, list, or even string will use heap anyway - they will take some space on the stack (like for small buffer optimization, or small string optimization), but they will allocate a chunk for the elements on the free store.

Let’s move to the first point now.

1. unique_ptr replaces auto_ptr

Maybe you’re a bit insulted by this point. I know you’re not that person that still uses auto_ptr… but let’s be honest, we all know auto_ptr is still hiding in our projects :)

Such pointers lurk from their caves and see a chance to cause bugs in the system!

But let’s be serious this time:

With C++11 auto_ptr got deprecated and in C++17 it’s removed from the standard. So we “got” 6 years to abandon and refactor old code.

For example, here’s what happens when compiling a code with auto_ptr with MCSV and conformance flag set to C++17 (/std:c++latest):

error C2039: 'auto_ptr': is not a member of 'std'

Notice that it’s an error, not a warning.

So what should you use instead?

Of course, it’s the hero of our story: unique_ptr!

The main advantage of using modern smart pointers is the ability to express ownership transfer properly. With auto_ptr you could easily get into troubles. Take a look here:

void doSomethig(std::auto_ptr<Test> myPtr){
myPtr
->m_value =11;
}

voidAutoPtrTest(){
std
::auto_ptr<Test> myTest(newTest());
doSomethig
(myTest);
myTest
->m_value =10;
}

What happens after doSomething() returns and we want to access myTest->m_value?

Or here’s the full playground:

In other words: auto_ptr is limited - mostly by not having move semantics supported at the time it was introduced. It’s also not reference counted (as shared pointers), so its use is somewhat cumbersome.

How to refactor your code? from WG21 N4190 :

auto_ptr has been superseded by unique_ptr. Any code using auto_ptr can be
mechanically converted to using unique_ptr, with move() inserted whenever
auto_ptr was being “copied”. clang-modernize’s Replace-AutoPtr Transform
does exactly this.

And here’s the link to clang: clang-tidy - modernize-replace-auto-ptr — Extra Clang Tools.

2. unique_ptr hides raw new and delete

A few days before I started writing this text I’ve seen the following Abseil/Google C++ guideline

abseil / Tip of the Week #126: make_unique is the new new

Plus there are a Core Guideline suggestions:

R.11: Avoid calling new and delete explicitly

The pointer returned by new should belong to a resource handle (that can call delete). If the pointer returned by new is assigned to a plain/naked pointer, the object can be leaked.

So… in other words: one of the parts of modern C++ is to avoid using raw new and delete. Instead, we should wrap allocated memory into RAII objects.

The main reasons why naked new and delete might cause harm are the following:

  • You need to remember to release the memory. It’s easy when it’s inside a little function… but for larger scopes it gets tricky. Moreover, you might need to interleave with other resources.
  • Naked pointers doesn’t show whose the real owner of a resource.

Whenever you see new try to replace it with a unique_ptr and make_unique.

3. Control the ownership of a pointer

MyType* pObject;

What can you deduce from the statement above?

And how about:

std::unique_ptr<MyType> pObject;

In modern C++ we head towards using raw pointers as a way to observe things, but the owners are in the form of smart pointers (or other RAII types).

Still, especially in legacy code, you cannot be sure what a raw pointer means. Is it for observation, or it’s an owning pointer?

Knowing who the owner is playing a core part when releasing the resource. It’s especially seen in factory (or builder) functions that return allocated objects:

MyType*BuildObject()
{
MyType* pObj =newMyType();
complexBuild
(pObj);
return pObj;
}

// ...
auto pObj =BuildObject();

The only way we had to express who should release the memory was through some guidelines or comments. But the compiler wouldn’t help in case of a bug and a leak.

With:

unique_ptr<MyType>BuildObject()
{
auto pObj = make_unique<MyType>();
complexBuild
(pObj.get());
return pObj;
}

// ...
auto pObj =BuildObject();

Now, the ownership is inside pObj, and it’s released when pObj goes out of scope.

4. Use inside functions

Every time you have to allocate an object on the free store, it’s useful to wrap it intounique_ptr.

A canonical example:

voidFuncMightLeak()
{
MyType* pFirst =newMyType();

if(!process())
{
delete pFirst;
return;
}

MyType* pSecond =newMyType();

if(!processSecond())
{
delete pFirst;
delete pSecond;
return;
}

process
();
delete pFirst;
delete pSecond;
}

Do you see how much effort needed to clean up the memory correctly? And it’s such a simple code - in real-life resource management code might be much more complex

And here’s the converted version that uses unique_ptr:

voidFuncNoLeaks()
{
auto pFirst = std::make_unique<MyType>();

if(!process())
return;

auto pSecond = std::make_unique<MyType>();

if(!processSecond())
return;

process
();
}

It looks almost like if the pointers were allocated on the stack.

What’s more, this could also work for other types of resources. So whenever you have to hold such things, you can think about RAII approach (using a smart pointer, custom RAII, custom deleter etc.)

Remark: the examples used memory allocated on the heap… but think if such objects can be allocated on the stack (see my 0th point). Not only it’s more straightforward but usually faster. Heap might be useful for huge objects (that wouldn’t fit into the stack space).

Play with the above code here:

5. Implement “pimpl” idom with unique_ptr

“Pointer to implementation” - “pimpl” is a conventional technique to reduce compile time dependencies. Briefly, it hides all (or some) details of the class implementation with some other type (that is only forward declared). Such technique allows changing the implementation without the need to recompile client code.

Here’s some code:

In the above example NetworkManager has a private implementation - NetManImpl which is hidden from the client code (main()). NetManImpl is implemented solely in a cpp file, so any changes to that class won’t cause the need to recompile client code - cpp_pimpl_client.cpp.

While this approach might sound like a lot of redundancy and redirection (see implementations of Connect or Disconnect methods that just redirects the calls) it makes modules physically independent.

You can read more @Fluent C++: How to implement the pimpl idiom by using unique_ptr.

Bonus - 6th reason!

By default, unique pointer uses delete (or delete[]) to free the allocated memory. This mechanism is good enough in probably like 99% of cases, but if you like, you might alter this behaviour and provide a custom deleter.

The thing to remember, according to the cppreference:

If get() == nullptr there are no effects. Otherwise, the owned object is destroyed via get_deleter()(get()).

Requires that get_deleter()(get()) does not throw exceptions.

In other words, the deleter is called when the managed pointer is not null.

Also, as deleter is part of the type of the unique pointer and may contribute to its size (if that’s a function pointer then it will take some space, if it’s only a stateless functor, then not).

Here’s an example:

In the above example, we need to provide a custom deleter to clean up ‘LegacyList’ objects properly.: ReleaseElements method must be called before the object is deleted. The cleanup procedure is wrapped into a stateless functor object:

structLegacyListDeleterFunctor{
voidoperator()(LegacyList* p){
p
->ReleaseElements();
delete p;
}
};

If you like to read more about custom deleters see:


Sorry for a little interruption in the flow :)
I've prepared a little bonus if you're interested in smart pointers - a reference card, check it out here:


Summary

I hope you’re convinced to start using unique_ptr in your projects :)

With this list, I’ve shown how this type of smart pointers leads to memory safety, code clarity, expressiveness and even much shorter code.

Do you have any cool examples how you used unique_ptr? Share your stories and observations.

Viewing all 325 articles
Browse latest View live