Meeting 30 August 2018

Embarcadero += Whole Tomato

Idera, Inc., parent company of global B2B software productivity brands, today announced the acquisition of Whole Tomato, the developer of the Visual Assist productivity tool for C++ developers in Visual Studio. Whole Tomato will join Idera, Inc.’s best-in-class Developer Tools businesses, including Embarcadero and Sencha.

Somewhere there, a sad ghost of Borland lives on.

Visual Studio 2017 version 15.8

  • Release notes
  • Blog post
    • Multi-caret editing!
    • A new, experimental, token-based preprocessor that conforms to C++11 standards
    • C++ Just My Code
    • Code analysis can now run in the background
  • Reddit thread
    • Reporting many regressions since 15.6

Using MSVC in a Windows Docker Container for Your C++ Projects

Post

Louis Brandy – Curiously Recurring C++ Bugs at Facebook – CppCon 2017

  • volatile does not make your code thread-safe
  • is shared_ptr thread-safe?
  • std::map::operator[]
1auto& ref = *returns_a_shared_ptr();
2ref.boom();
  • use Address Sanitizer (--fsanitize-address-use-after-scope)

Broken:

1const string& get_default(
2    const map<string, string>& map,
3    const string& key,
4    const string& dflt)
5{
6    auto pos = map.find(key);
7    return pos != map.end() ? pos->second : dflt;
8}

Does this compile?

1#include <string>
2
3void f() {
4    std::string(foo);
5}

Does this compile?

1#include <string>
2
3void f() {
4    std::string(foo);
5    std::string{foo};
6}

Problem:

1void Object::update() noexcept {
2    unique_lock<mutex>(m_mutex);
3    do_update();
4}

Fix:

1void Object::update() noexcept {
2    unique_lock<mutex> lock(m_mutex);
3    do_update();
4}

C++ Cryptozoology, by Adi Shavit

Bestiary

Abominable function types

Impossible to create:

1using abominable = void() const volatile &&;

Flying saucers

1class Point {
2    int x, y;
3public:
4    auto operator<=>(Point const&) const = default;
5    // totally-ordered member-wise comparison
6}

UB Demons

1#include <cstdlib>         // for system()
2typedef int (*Function)(); // define function pointer type
3static Function Do;        // define function pointer default-initialized to 0
4static int Nuke()  { return system("rm -rf /"); }
5void NeverCalled() { Do = Nuke; }   // this function is never called!
6int  main()        { return Do(); } // call default-initialized function = UB

GCC generated assembly:

1main:
2    movl $.L.str, %edi
3    jmp system
4
5.L.str:
6    .asciz "rm -rf /"

East const

Writing Swift in C++

1#define func auto
2#define var auto
3#define let auto const
4
5func len(std::string s) -> size_t {
6    let length = s.size();
7    return length;
8}

Type functions and beyond: An exploration of type functions and concept functions, by J. Monnon

P0844

This document proposes to extend functions to let them operate directly on types and concepts. The goal is to allow writing metaprogramming in the most intuitive and consistent way with the rest of the language.

1ForwardIterator IteratorType(typename T) {
2    // In a type function, an `if` behaves as a `if constexpr`.
3    if (Container(T))  // `Container` is a concept
4        return T::iterator;
5    else if (Array(T)) // `Array` is a concept
6        return Decay(T);
7}
8// On call site:
9typename I = IteratorType(C);

P0844

Concept functions are introduced to manipulate and transform concepts. One of the simplest examples of concept function is to create a new concept by adding constraints to an existing one:

1// Adds the constraints of the `Serialize` concept to any concept.
2concept Serializable(concept C) {
3    return C && Serialize;
4};
5
6// On call site:
7template<Serializable(Container) C>

FizzBuzz at compile time

Article

This program is impossible to outperform with respect to run-time performance; it will actually never run! And here’s the nice touch: the program will deliberately not even compile! The interesting part is that as error message, the compiler outputs the FizzBuzz solution.

\Main.cpp(36) : error C2039: 'compilation_error_here' : is not a member of
 'boost::mpl::vector101 <SNIP long argument list>'
    with
    [
         T0=boost::mpl::int_<0>,
         <...>
         T3=Fizz,
         T4=boost::mpl::vector<boost::mpl::int_<4>>,
         T5=Buzz,
         <...>
         T15=FizzBuzz,
         <...>
    ]

CppCon 2018 - Vinnie Falco - Interactive Websites: Using Boost.Beast WebSockets and Networking TS

Announcement

Related:

  • RESTinio - a header-only C++14 library that gives you an embedded HTTP/Websocket server. It is based on standalone version of ASIO and targeted primarily for asynchronous processing of HTTP-requests. Since v.0.4.1 Boost::ASIO (1.66 or higher) is also supported.

How to CMake Good

CMake It Modern Using C++ and Qt

How to specialize std::sort by binding the comparison function, by Herb Sutter

1auto sort_down = bind(sort<vector<int>::iterator,function<int(int)>>,
2                      _1, _2, [](int x, int y) { return x > y; });

Use lambdas, don’t use bind(). Even if you think bind() is better, don’t. Sincerely, STL maintainer who rewrote bind() from scratch. – STL

1auto sort_down = [](auto a, auto b) {
2  return sort(a, b, [](int x, int y) { return x > y; });
3};

Spaceship Operator, by Simon Brand

Article

1(a <=> b) < 0  // true if a < b
2(a <=> b) > 0  // true if a > b
3(a <=> b) == 0 // true if a is equal/equivalent to b

Example

1struct foo {
2  int i;
3
4  std::strong_ordering operator<=>(foo const& rhs) {
5    return i <=> rhs.i;
6  }
7};

Note that whereas two-way comparisons should be non-member functions so that implicit conversions are done on both sides of the operator, this is not necessary for operator<=>; we can make it a member and it’ll do the right thing.

1auto operator<=>(x const&) = default;

Mathematics behind Comparison, by Jonathan Müller

Variadic CRTP

Quote

Tony Hoare:

Concurrent programs wait faster.

Twitter