Skip to main content

20 posts tagged with "c++"

View All Tags

· One min read
Hreniuc Cristian-Alexandru

I had to create a conditional singleton object and I tried something but it didn't look so good. And while doing this I've noticed that I colleague did something like this:

static const auto executor = []() -> smt_type
{
return smt;
}();

Which creates a lamba and calls it inplace.

And I liked it so much that I ended up asking him about it and he showed me this post from Herb Sutter. So I ended up doing something like this:

static const auto executor = []() -> std::shared_ptr<Aws::Utils::Threading::PooledThreadExecutor>
{
if(!isActive())
{
return nullptr;
}
size_t workers{0};
auto const downloadWorkersStr = getenv("env_var");
if(downloadWorkersStr)
{
// Env variable overrides the config
workers = stoi(downloadWorkersStr);
}
else
{
workers = getWorkerThreadsFromConfig();
}

if(workers == 0)
{
workers = boost::thread::hardware_concurrency();
}
return Aws::MakeShared<Aws::Utils::Threading::PooledThreadExecutor>(
"", workers);
}();
return executor;

This is called only once and it's also thread safe.

· One min read
Hreniuc Cristian-Alexandru

Source: https://doc.qt.io/qtcreator/creator-debugging-helpers.html#adding-custom-debugging-helpers

find ~ -name personaltypes.py

/home/cristi/Qt/Tools/QtCreator/share/qtcreator/debugger/personaltypes.py

Add there the following contents:

def qdump__ClassType1(d, value):
m_member1 = value["m_member1"].integer()
m_member2 = value["m_member2"].integer()
miliseconds = int(m_member1 * 1000 / m_member2)
d.putNumChild(0)
d.putValue(str(miliseconds) + str("ms (")+ str(m_member1) + str("m1, ") + str(m_member2) + str("m2)"))

def qdump__ClassType2(d, value):
position = value["m_position"]
d.putNumChild(0)
qdump__FramesDuration(d, position)

The ClassType2 will be displayed like this: 3642331ms (160626834m1, 44100m2).

For more examples, check: /home/cristi/Qt/Tools/QtCreator/share/qtcreator/debugger/stdtypes.py.

· One min read
Hreniuc Cristian-Alexandru

I've found this. I haven't tried it, but I want to save it just in case.

Contents:

Boost has experimental CMake support. You have to do a bit of dev to get it working but we've had good experiences so far.

set(BOOST_INCLUDE_LIBRARIES system thread) # enabled libraries
set(BOOST_ENABLE_CMAKE ON) # CMake support
FetchContent_Declare(boost GIT_REPOSITORY https://github.com/boostorg/boost.git ...

The above will get you the compiled libs working. For the header library (Boost::boost aka Boost::headers) there doesn't seem to be CMake support as yet so we wrote a few lines of CMake code to iterate through the FetchContent source directory and added all include folders to a new IMPORTED INTERFACE target.

· 2 min read
Hreniuc Cristian-Alexandru

Tools

# Make sure pip is using python3
pip install conan

# Cmake
sudo apt-get install cmake

# gcc + make
sudo apt-get install build-essential

Install clang for automatic formatting:

#!/bin/bash

# Use this script to install the clang formatter and all its utilities.
# Install Clang(Used for clang-format)
# ============================================================================ #
mkdir -p ~/programs/clang && cd ~/programs/clang &&
# http://releases.llvm.org/download.html
clang_version="9.0.0" &&
archive_name="clang+llvm-${clang_version}-x86_64-linux-gnu-ubuntu-18.04" &&
wget http://releases.llvm.org/${clang_version}/${archive_name}.tar.xz &&
tar xf ${archive_name}.tar.xz &&
rm -Rf ${archive_name}.tar.xz &&
unlink clang_latest # Just in case there was another sym link
ln -sf ${archive_name} clang_latest &&
(
echo "CLANG_INSTALL_PATH=\"/mnt/programs/clang/clang_latest\"" &&
echo "export PATH=\"\${CLANG_INSTALL_PATH}/bin:\$PATH\"" &&
echo -n "export LD_LIBRARY_PATH=\"\${CLANG_INSTALL_PATH}/lib" &&
echo ":\$LD_LIBRARY_PATH\""
) >> ~/.bashrc
# ============================================================================ #

IDE

Use QtCreator.

Activate these plugins:

Go to Help -> About plugins:
- C++
- Check ClangCodeModel
- Check ClangFormat
- Beautifier
- Code Analyzer
- Check ClangTools
- Utilities
- Check Todo

Set these settings:

Go to Tools -> Options:
- Text Editor
- Behavior:
- Tab policy: Spaces Only
- Tab size: 2
- Indend size: 2
- Align continuation lines: With Spaces
- Clean whitespace (upon saving)
- Display:
- Display right margin at column: 80
- Display line numbers
- Display folding markers
- Visualize whitespace
- Highlight search results on the scrollbar
- Highlight current line
- Highlight blocks
- Animate matching parentheses
- Highlight matching parentheses
- Completion:
- Enable Doxygen blocks
- Generate brief description
- Add leading asterisks
- Beautifier
- Enable auto format on file save
- Clang Format
- Use predefined style: `File`
- Debugger
- General:
- Set breakpoints using full absolute path

· 6 min read
Hreniuc Cristian-Alexandru

We wanted to optimize the way we combine multiple protobuf messages. Our scenario was this, we had a NestedRepeatedMessage that contained a NestedSingleInt message. We were creating a NestedRepeatedMessage which was the same for multiple users, so were serializing it once and we were posting it to be sent to that user. After some tests, we detected that sending 1 message per send operation is verry expensive, so we had to find a solution to combine multiple serialized messags before sending them.

The first solution was to, keep a reference to the protobuf object that was used to serialize, and if the client had multiple messages in the queue, we would create a big NestedRepeatedMessage and we would create a copy of each NestedSingleInt from those NestedRepeatedMessage from the queue. If there was only one element in thew queue, we would use the serialized version. This was also expensive..

Our next step, was to find a way to use the already serialized string. After understanding how the the protobuf encoding works, we've noticed that if append the serialized NestedRepeatedMessage messages, it results the same serialized string as the one from above, where we were doing a copy of all messages, adding them to a big message and then re-serializing it.

Below you can find all steps that were done to get to this conclusion.

· One min read
Hreniuc Cristian-Alexandru

If you return a value from a method and you assing it to the a const reference, that value will be kept alive as long as the const reference is alive:

string get() { return "string"s; }

int main()
{
const string& ref_to_temp = get();
cout << ref_to_temp << endl;
}

Better explaination: https://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/ or stackoverflow: https://stackoverflow.com/questions/2784262/does-a-const-reference-class-member-prolong-the-life-of-a-temporary

Or standard explaination: 8.5.3/5, here

· 2 min read
Hreniuc Cristian-Alexandru

We had an issue in our server, there were some dataraces. After an investigation we've detected that when we were posting inside a strand, we were using the get_inner_executor() method from the strand, and this resulted in posting the handler to the io_context that was used when creating the strand, it wasn't used the strand, which meant no serialization.

An example of code can be found below.

· 3 min read
Hreniuc Cristian-Alexandru

Some things were taken from this post, be sure to check it out.

Prepare pretty printers for GDB

The first thing you should always do is to get the pretty printers and use them to print the variables in gdb. To do this you will need to find the install path of thec gcc that was used to build the executable that has generated a coredump, and inside that path there should be some pretty printers. Usually, this path can be found here(on ubuntu): /usr/share/gcc-10/python/.

In my case it was in /opt/gcc/9.2.0/share/gcc-9.2.0/python/, because the gcc that I was using was built from sources.

That folder contains a folder called: libstdcxx which contains some python scripts that are used to print the variables nicer.

If you are investigating a coredump on a different server, you can copy that folder to the server using scp: scp -r /usr/share/gcc-10/python/ user@server:/path/to/server/.

Activate the pretty printers from the gdb config file

Pretty printers, added this in ~/.gdbinit:

python
import sys
# gcc-9
sys.path.insert(0, '/usr/share/gcc/python')
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (None)
end

# Will print the whoile object
set pagination off
set print array on

# It will format the output
set print pretty on

· 7 min read
Hreniuc Cristian-Alexandru

How much faster it is to have a vector of objects instead of pointers.

Compile the code from below and run it:

g++ -std=c++17 -O3 -g -o exe main.cpp

Ussage: ./exe iterations entries_per_vector no_tests [shared_ptr|object] [pre-allocated]

☰ dockerfile ⑂master_interactive* ♦ gcc --version
gcc (Ubuntu 9.2.1-9ubuntu2) 9.2.1 20191008

Not prealocated: - Storing a vector of objects is 2 times faster.