Category Archives: C++

C++ tasks from Yandex

Task 1

At an interview I was asked how to by a given vector of integers build resulting vector containing the products of all the elements except current. Below I provided my solution in C++:

#include <vector>
#include <iostream>

using V = std::vector<int>;

V func(const V& v)
{
    V result;
    result.resize(v.size());

    int product = 1;

    for (size_t pos = 0; pos != v.size(); ++pos)
    {
        result[pos] = product;

        int a = v[pos];
        product *= a;
    }
(more…)

Range-based for loop with universal reference.

It is possible to iterate over std::vector with &&:

#include <vector>

class A {};

int main()
{
    std::vector<A> vec;
    for (auto&& v : vec)
    {
        static_cast<void>(v);
    }

    return 0;
}

Links:

An annoying question about auto in C++

I was recently asked during a C++ job interview what are the types of riN variables in the code below:

int val = 25;

int foo() { return val; }
int& foo1() { return val; }
//warning: type qualifiers ignored on function return type
/*const*/ int foo2() { return val; }
const int& foo3() { return val; }

int main()
{
  auto ri = foo(); 
  auto ri1 = foo1();
  auto ri2 = foo2();
  auto ri3 = foo3();

  //cannot bind non-const lvalue reference of type 'int&' to an rvalue of type 'int'
  //auto& ri4 = foo();
  auto& ri5 = foo1();
  //cannot bind non-const lvalue reference of type 'int&' to an rvalue of type 'int'
  //auto& ri6 = foo2();
  auto& ri7 = foo3();

  auto&& ri8 = foo();
  auto&& ri9 = foo1();
  auto&& ri10 = foo2();
  auto&& ri11 = foo3();
    
  return 0;
}

auto ignores the type qualifiers and references, so looks like the types are simply int, int& and int&&.

Negating the minimal integer results in an overflow in C++

The code below compiles with a warning:

#include <iostream>
#include <limits>
#include <cstdint>

int main()
{  
    int64_t m1 = -std::numeric_limits<int64_t>::min();
    int64_t m2 = -m1;
    
    std::cout << m1 << std::endl << m2 << std::endl << std::numeric_limits<int64_t>::max() << std::endl;
    
    return 0;
}
(more…)

The sum of signed and unsigned is unsigned in C++

#include <iostream>

template <typename T>
void PrintValue(T val)
{
    if constexpr (std::is_signed_v<T>)
    {
        std::cout << "signed";
    }
    else
    {
        std::cout << "unsigned";
    }

    std::cout << std::endl << val << std::endl;
}
(more…)

None of C++ compilers have heterogeneous lookup for unordered containers except MSVC

At 10/20/2020:

And std::vector is not constexpr yet:

And there is no text formatting also.

Coroutines:

std::chrono::days:

See C++20 library features compiler support.

Brain collapsing rules in C++

Consider the declaration of a class that contains a lambda function or a reference to it:

#include <utility>

template <class Func>
struct Holder
{
    Holder(Func && func) : m_func(std::forward<Func>(func))
    {
    }

    Func m_func;
};

template <class Func>
auto MakeHolder(Func && func)
{
    return Holder<Func>(std::forward<Func>(func));
}
(more…)

Why my QT app crashes at the destructor of std::thread on Android 10 devices?

I did some research on why my QT app crashes at the destructor of std::thread on Android 10 devices at the user side with the following call stack:

#00 /apex/com.android.runtime/lib64/bionic/libc.so (abort+160)
#01 /system/lib64/libc++.so (abort_message+232)
#02 /system/lib64/libc++.so (demangling_terminate_handler()+44)
#03 /system/lib64/libc++.so (std::__terminate(void (*)())+12)
#04 /system/lib64/libc++.so (std::terminate()+52)
#05 /system/lib64/libc++.so (std::__1::thread::~thread()+20)
#06 /apex/com.android.runtime/lib64/bionic/libc.so (__cxa_finalize+212)
#07 /apex/com.android.runtime/lib64/bionic/libc.so (exit+24)
#08 /data/app/com.domain.myapp-Rs_sm5VrLR1Jj8QW6oYByA==/lib/arm64/libplugins_platforms_qtforandroid_arm64-v8a.so

and figured out that its likely because std::thread destructor is being invoked while the thread is still joinable at some point of the application execution (thanks to G. M. on stackoverflow.com).

(more…)

C++ binary serialization speed is comparable with std::memmove

Measuring std::memmove speed

I wrote a simple test that outputs std::memmove speed to the console:

AWT_ATTRIBUTE(size_t, element_count, 1000000);

std::unique_ptr<uint8_t> p_src(new uint8_t[element_count]);
std::memset(p_src.get(), 25u, element_count);

std::unique_ptr<uint8_t> p_dst(new uint8_t[element_count]);

context.out << _T("std::memmove: ");

awl::StopWatch w;

std::memmove(p_dst.get(), p_src.get(), element_count);

ReportSpeed(context, w, element_count);

context.out << std::endl;

And the similar tests for std::memset and std::vector::insert.

(more…)

A funny example of C++ code that MS can compile :)

In the code below, static_assert operates on the addresses of local variables, but however MS compiles it and the assertion does not fail:

#include <tuple>
#include <string>
 
struct A
{
    int a;
    double b;
    std::string c;
};
 
void f()
{
    A a{ 1, 3.0, "abc" };
    constexpr auto t1 = std::tie(a.a, a.b, a.c);
    static_assert(&std::get<0>(t1) == &a.a);
}

Use the following command to compile this example:

cl /std:c++17 /EHsc a.cpp
(more…)