Browsing Qt’s source code using Woboq

If you want to browse Qt framework’s source codes using your browser, Woboq is a great tool. It allows to browse C/C++ codes in the browser with the same look and feel that you get from your modern IDE. It features semantic highlighting and contextual tool tips that makes it easier to read C++ code.

Following is the URL where Qt’s source is hosted.
https://code.woboq.org/qt5/qtbase/

Although we could navigate the source code using IDE like Qt Creator, being able to read codes through a browser becomes handy while development.

You can see the bottom right of the browser to see from which revision/version the source code has been generated. For example for Qt’s qtbase, it might look as follows:
Generated on 2017-May-28 from project qtbase revision v5.9.0-beta3-521-g9609e2945

Apart from Qt project, Woboq also hosts several other popular open source projects like boost, LLVM, GCC and linux.

See the following link to browse the source code of these projects.
https://code.woboq.org/

Advertisements

Online C++ compilers

There are various online C++ compiler that lets you to try out newest C++ features. You can choose for different types and versions of compiler like gcc, clang etc. If you don’t want to install these C++ compilers on your machine, and quickly want to test small C++ snippets to check various latest C++ features then online C++ compiler can be a great tool.

After researching a little bit, I really loved the following two:

1. wandbox
URL: https://wandbox.org/

2.Coliru
URL: http://coliru.stacked-crooked.com

wandbox is my first choice to test C++17 features as it is most up-to-date with GCC and Clang versions. Above all it support multiple files which is really handy for dealing with multiple files.

The blog post by Arne Mertz was very helpful to find these great tools.

Basic makefile project to build and test C++ projects quickly

This post shows how to setup a simple make file in order to build and test C++ applications quickly.

The folder structure looks as follows:
├── app.cpp
├── makefile
├── mylib.cpp
├── mylib.h

The make file defines the name of the project, includes the source and header files, defines a C++ compiler and other flags that can be passed to the compiler.

PROJECT		= make_starter

SRCS 		= app.cpp \
              mylib.cpp

OBJS		= app.o \
              mylib.o 

TARGET		= test_starter

CXX			= g++

CXXFLAGS	= -std=c++11

INCLUDE 	= -I./

all:
	$(CXX) -c $(CXXFLAGS) $(SRCS) $(INCLUDE)
	$(CXX) $(OBJS) -o $(TARGET) $(LIBS)

clean:
	rm $(OBJS) $(TARGET)

The main function for the application is defined in app.cpp file. In mylib.h and mylib.cpp, a simple function is declared and defined that is used in app.cpp.

To build the project, execute the following

$make

To run,

$./test_starter

The program should output the following texts:

Starter project using make...
Printed from myfunc

All source codes can be found in this link.

Using gdb to debug C++ programs in linux environment

GDB is a debugger that helps to debug programs written in C and C++. Most of the modern IDE is already integrated with some debugging tools, so it is seamless for a user to debug programs using these IDE’s. However when we have no IDE and working on a command line, knowing how to debug programs using GDB in a command line becomes really helpful. This post describes the basic steps necessary for debugging programs using GDB.

Let us consider we have a following cpp file.


#include <iostream>
#include <vector>
#include <map>
#include <string>

using namespace std;

int main()
{
    cout << "gdb debugger demo..." << endl;

    int size  = 10;
    std::string name = "hello";

    vector<int> i_vec;
    i_vec.push_back(10);
    i_vec.push_back(20);
    i_vec.push_back(30);

    cout << "Size of a vector: " << i_vec.size() << endl;

    map<string,int> name_age_map = {{"Bob",30},{"Harry",45},{"Susan",26}};
    cout << "Size of a map: " << name_age_map.size() << endl;

    cout << "End of program" << endl;
}

In order to be able to debug this program, we have to compile the source using -g option as follows:

$ g++ -g source.cpp

This will create a.out as we have not specified an output file. Also to enable the compilation with C++ 11 features, we need to add the option -std=c++11 as follows:

$ g++ -std=c++11 -g source.cpp

To start GDB, execute the following

$ gdb a.out

This will enter into GDB session and the prompt (gdb) appears as shown below:

(gdb)

Once we are in the gdb prompt, we can type various gdb commands. To list the programs with the line number,execute the following:

(gdb) l
1       #include <iostream>
2       #include <vector>
3       #include <map>
4       #include <string>
5
6       using namespace std;
7
8       int main()
9       {
10          cout << "gdb debugger demo..." << endl;

By default GDB displays 10 lines of code. This can be changed using a command [set listsize count].

To list the next 10 lines, we can type l or list in the (gdb) prompt.

To set a break point, use the command “break” as follows:

(gdb) break 16
Breakpoint 1 at 0x401143: file demoapp.cpp, line 16.
(gdb)

The above command sets the break point at line number 16.

To query how many break points are currently set, execute the following command.

(gdb) info breakpoints
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000000000401143 in main() at demoapp.cpp:16
        breakpoint already hit 1 time
2       breakpoint     keep y   0x0000000000401143 in main() at demoapp.cpp:16
        breakpoint already hit 1 time

After the breakpoints have been set, we can start the debugging process as follows:

(gdb) r
Starting program: /home/ashrestha/projects/mygit/CppTestGround/sandbox/linux/gdbtest/a.out
gdb debugger demo...

Breakpoint 1, main () at demoapp.cpp:16
16          i_vec.push_back(10);
(gdb)

This will run the program till the first breakpoint is hit and it waits for the user input to proceed further. At this point we can execute various commands to observe the state of variables, step through the function calls etc. For example to observe the state of a variable, we can execute the following commands:

(gdb) p size
$1 = 10
(gdb) p name
$2 = "hello"
(gdb) p i_vec
$3 = std::vector of length 0, capacity 0
(gdb)

To step over to the next line of code, execute the following:

Breakpoint 1, main () at demoapp.cpp:16
16          i_vec.push_back(10);
(gdb) n
17          i_vec.push_back(20);
(gdb) n
18          i_vec.push_back(30);
(gdb) n
20          cout << "Size of a vector: " << i_vec.size() << endl;
(gdb)

To continue to rest of the program, execute the following:

(gdb) c
Continuing.
Size of a vector: 3
Size of a map: 3
End of program
[Inferior 1 (process 13251) exited normally]
(gdb)

To quit GDB, execute the following:

(gdb) q

This covered just the basic commands that is absolutely necessary to debug a program. There are many more commands that can be used with the GDB.

Refer to this link for a GDB Debugger command sheet.

For comprehensive manual, refer to Debugging with GDB.

All source code for this post can be found here.

Qt QML and Html5 comparison study

I recently read an interesting white paper published by Sequality which is an Austrian software consulting company. This paper compares the difference between QML and Html5 for developing a UI that consists of a dashboard for an industrial application. It describes the development work that is needed to create the application using two different technologies by the same developer within 160 hours timeframe, and compares the technologies from a technical and economic perspective.

The test was carried out for developing an application for embedded devices. Technically, both Qt and Html5 could be used for UI, the pros of using QML declarative UI language far surpasses in terms of development effort, testing and debugging process and responsiveness.

Using Html5 or other JavaScript frameworks for UI development is both challenging in terms of maturity of these frameworks. The JavaScript frameworks evolves rapidly and there is a concern for browser compatibility issues because different browsers use different rendering engines. Also the backward compatibility is a major issue with this technology.

With Qt/C++ and QML combination, there is a less worry in terms of backward compatibility issue. As Qt is a mature C++ framework, the support for it is great and one can think of this technology as a sustainable solution.

The paper also mentions how it was easy to do a low level communication with the hardware. For example using QML, we can write all low level codes in a backend C++ classes and these can be consumed by QML declarative language in a more intuitve ways. This is not a straightforward task if you use Html5 technology. Here you have to route signal through the http-server, browser and javascript to Html5. In terms of performance also, QML version is faster and consumes less battery power than Html5.

In conclusion, I would definitely vote for QML approach as opposed to Html5 when you are developing UI for your next embedded device application like home automation, automobile dashboard, coffee machine interface etc…

A link to the whitepaper can be found here.

Unit testing in C++ using CATCH and QtCreator

This is a first blog post on unit testing framework using CATCH. CATCH stands for C++ Automated Test Cases in Headers. And it is really easy to get started with CATCH. Some of the key features of CATCH are:

There is no external dependencies. By just including one header file, you are on your way to write your test cases. The only thing that you need is a C++ compiler.

You can write test cases as self-registering functions or methods.

Divide test-cases into sections where each of the sections can be run in isolation. This is a nice feature where unlike other testing frameworks like GTest and CppUnit, you don’t need fixtures!

These are just few of the benefits that CATCH provides. For more comprehensive description regarding CATCH, see here.

I wanted to integrate CATCH in my Qt projects. So, I used QtCreator as my IDE with gcc 5.4 on Ubuntu 16.04.

Following sections describe the project structure in more detail.

The project structure looks as shown below:

── app
│ ├── app.pro
│ └── main.cpp
├── defaults.pri
├── MyProject.pro
├── MyProject.pro.user
├── README.md
├── src
│ ├── camera.cpp
│ ├── camera.h
│ ├── myclass.cpp
│ ├── myclass.h
│ ├── myserialcommunication.cpp
│ ├── myserialcommunication.h
│ └── src.pro
├── tests
│ ├── catch.hpp
│ ├── main.cpp
│ └── tests.pro
└──

MyProject.pro is the main project file based on subdirs template. It looks as shown below:

TEMPLATE = subdirs
CONFIG+=ordered
SUBDIRS = \
    src \
    app \
    tests

app.depends = src
tests.depends = src

OTHER_FILES += \
    defaults.pri

The src folder contains code that will be part of a library. The app folder contains the main.cpp for testing the library source code. And tests folder contains the main.cpp that runs the unit testing using CATCH. The code app.depends and test.depends make sure that src project is compiled before app and tests so that the library code can be used by both app and tests. Here defaults.pri is the helper project file that will be used by other .pro files so that the header files are available in these projects.

The content of defaults.pri looks as shown below:

INCLUDEPATH += $$PWD/src
SRC_DIR = $$PWD

The main library code is located in src folder. The src.pro file is the main project file which is described as follows:

include(../defaults.pri)
CONFIG   += console
CONFIG   -= app_bundle
QT += serialport
TEMPLATE = lib

TARGET = myapp

SOURCES += myclass.cpp \
    camera.cpp \
    myserialcommunication.cpp
HEADERS += myclass.h \
    camera.h \
    myserialcommunication.h

The project file defines qmake variables like CONFIG, SOURCES, HEADERS etc to perform the build process. For this project, three classes are declared and defined in .h and .cpp as follows:

#ifndef MYCLASS_H
#define MYCLASS_H

class MyClass {
public:
    double addition(double a, double b);
    double product(double a, double b);
};

#endif // MYCLASS_H
#include "myclass.h"

double MyClass::addition(double a, double b) {
    return a + b;
}

double MyClass::product(double a, double b) {
    return a * b;
}
#ifndef CAMERA_H
#define CAMERA_H

#include <QtSerialPort/QSerialPort>

class Camera
{
public:
    Camera();

    double getCenterX();
    double getCenterY();
    double getCenterZ();
};

#endif // CAMERA_H
#include "camera.h"

Camera::Camera()
{

}

double Camera::getCenterX()
{
    return 10.0;
}

double Camera::getCenterY()
{
    return 20.0;
}

double Camera::getCenterZ()
{
    return 30.0;
}
#ifndef MYSERIALCOMMUNICATION_H
#define MYSERIALCOMMUNICATION_H

#include <QString>

class MySerialCommunication
{
public:
    MySerialCommunication();

    QString getAllSerialPortInfo();
};

#endif // MYSERIALCOMMUNICATION_H
#include "myserialcommunication.h"
#include <QtSerialPort/QSerialPortInfo>
#include <QStringList>
#include <QObject>

MySerialCommunication::MySerialCommunication()
{
}

QString MySerialCommunication::getAllSerialPortInfo()
{
    QStringList serialPortInfos;

    const auto infos = QSerialPortInfo::availablePorts();
    for (const QSerialPortInfo &info : infos) {
        QString sportInfo = QObject::tr("Port: ") + info.portName() + "\n"
                + QObject::tr("Location: ") + info.systemLocation() + "\n"
                + QObject::tr("Description: ") + info.description() + "\n"
                + QObject::tr("Manufacturer: ") + info.manufacturer() + "\n"
                + QObject::tr("Serial number: ") + info.serialNumber() + "\n"
                + QObject::tr("Vendor Identifier: ") + (info.hasVendorIdentifier() ? QString::number(info.vendorIdentifier(), 16) : QString()) + "\n"
                + QObject::tr("Product Identifier: ") + (info.hasProductIdentifier() ? QString::number(info.productIdentifier(), 16) : QString()) + "\n"
                + QObject::tr("Busy: ") + (info.isBusy() ? QObject::tr("Yes") : QObject::tr("No")) + "\n";

        serialPortInfos << sportInfo;
    }

    QString result = serialPortInfos.join(", ");

    return result;
}

This library code is used in app project. And the unit testing for these classes are written in tests folder which are described in the following sections.

First,in the app folder, the app.pro project file is defined as follows:

include(../defaults.pri)

CONFIG += console
CONFIG -= app_bundle
QT += serialport

TEMPLATE = app

SOURCES += main.cpp

LIBS += -L../src -lmyapp

QT += serialport is required as we are using QSerialPortInfo in the class MySerialCommunication.

The main function looks as follows:

#include <iostream>
#include <myclass.h>
#include <camera.h>
#include <myserialcommunication.h>

using namespace std;

int main()
{
    MyClass mathoperations;
    cout << "Result of addition: " << mathoperations.addition(10, 20) << endl;
    cout << "Result of product: " << mathoperations.product(4,5) << endl;

    Camera camera;
    cout << "Center X: " << camera.getCenterX() << endl;
    cout << "Center Y: " << camera.getCenterY() << endl;
    cout << "Center Z: " << camera.getCenterZ() << endl;

    MySerialCommunication serialComm;
    cout << "SerialPortInfo: \n" << serialComm.getAllSerialPortInfo().toStdString() << endl;

    return 0;
}

As mentioned above, all unit tests for the library source code are written in tests folder. The project file tests.pro is defined as follows:

TEMPLATE = app

include(../defaults.pri)

CONFIG += console
CONFIG += c++14
CONFIG -= app_bundle
#CONFIG -= qt
QT += serialport

SOURCES += main.cpp

LIBS += -L../src -lmyapp

And the main.cpp file is defined as follows:

#define CATCH_CONFIG_MAIN  // This tells Catch to provide a main() - only do this in one cpp file
#include "catch.hpp"
#include <myclass.h>
#include <camera.h>

TEST_CASE( "MyMath", "[mymath]" ) {
    SECTION("Addition") {
        MyClass my;
        REQUIRE(my.addition(3,4) == 7);
    }
    SECTION("Multipication") {
        MyClass my;
        REQUIRE(my.product(3,4) == 12);
    }
}

TEST_CASE("MyCamera","[mycamera]")
{
    SECTION("CenterX") {
        Camera camera;
        REQUIRE(camera.getCenterX() == 10.0);
    }
    SECTION("CenterY") {
        Camera camera;
        REQUIRE(camera.getCenterY() == 20.0);
    }
    SECTION("CenterZ") {
        Camera camera;
        REQUIRE(camera.getCenterZ() == 30.0);
    }
}

In order to use CATCH, we need to include catch.hpp header file. This has been placed in the tests folder itself for simplicity. In the main.cpp file, the line #define CATCH_CONFIG_MAIN tells CATCH to provide main() function. Next is to include catch.hpp file itself. Then all other C++ headers for which we need to write unit tests are included. It is also possible to write separate unit test files for each individual classes which is infact a best practice. However, for demo purpose, unit tests for all classes have been included in a single cpp file.

In the next blog series, I’ll go in more depth usage of CATCH.

All source codes are available here.

Implementing generic Linked List using C++ Templates

Linked list is a data structure in which the elements are stored where each node element contains a link to its successor in the case of singly linked list; and a link to both its successor and predecessor if it’s a doubly linked list. The type of an element that is stored in a linked list may be a fundamental data type or any user defined type. A container such as linked list is a good candidate for leveraging the C++ templates. In fact std::list from STL is implemented as doubly linked list using templates.

In this post, we will try to build a very simple singly linked list data structure. The aim here is not to build a robust linked list, but to illustrate how templates can be used for building such generic containers.

First let us start with a very basic Node class as follows:

class Node
{
public:
    explicit Node(int value)
        : m_value(value) {}
    ~Node() {}

    int getValue() { return m_value; }

    std::shared_ptr<Node> getNext()
    {
        return m_next;
    }

    void setNext(std::shared_ptr<Node>& next)
    {
        m_next = next;
    }

private:
    int m_value;
    std::shared_ptr<Node> m_next;
};

The object of Node class can hold an integer data and point to the next Node object that also holds the integer data. So, we can define a chain of nodes where the first node would be a head node and the last node will be a tail node. For example, in the following node chain
10->20->30
10 is the head node and 30 is the tail node.

The above Node class can be used as follows:

void nodeChainsDemo()
{
    auto first = std::make_shared<NodeChains::Node>(10);
    auto middle = std::make_shared<NodeChains::Node>(20);
    auto last = std::make_shared<NodeChains::Node>(30);

    first->setNext(middle);
    middle->setNext(last);

    NodeChains::printNodeChains(first);
}

We can print the value of this node chain with a method printNodeChains() which is defined as follows:

void printNodeChains(std::shared_ptr<Node>& node)
{
    auto temp = node;
    while (temp != nullptr) {
        std::cout << temp->getValue() << std::endl;         temp = temp->getNext();
    }
}

The output of this is obviously 10 20 30.

One problem with the above Node class is that, it is specific to integer type only. What if we want to use the same Node class for other data types like float, string or MyClass.

We can use class template to define such a node functionality which can hold any data types.

A LinkedListNode class can be defined as follows:

template <typename T>
class LinkedListNode {
public:
    explicit LinkedListNode(T value)
    : m_value(value){

    }

    LinkedListNode() {}

    T getValue() { return m_value;}

    std::shared_ptr<LinkedListNode<T>> getNext()
    {
        return m_next;
    }

    void setNext(std::shared_ptr<LinkedListNode<T>>& next)
    {
        m_next = next;
    }

private:
    T m_value;
    std::shared_ptr<LinkedListNode<T>> m_next;
};

template<typename T>
void printList(std::shared_ptr<LinkedListNode<T>>& node)
{
    auto temp = node;
    while (temp != nullptr) {
        std::cout << temp->getValue() << std::endl;         temp = temp->getNext();
    }
}

This class is essentially similar to the previous Node class, except the concrete type is replaced by type T.
A non-member function printList() is also provided that takes a pointer to LinkedListNode and iterates over all its elements to print its values.

The LinkedListNode class can be used as illustrated below:

void linkedListNodeDemoWithString()
{
    auto first =
        std::make_shared<LinkedList::LinkedListNode<std::string>>("Node1");

    auto middle =
        std::make_shared<LinkedList::LinkedListNode<std::string>>("Node2");

    auto last =
        std::make_shared<LinkedList::LinkedListNode<std::string>>("Node3");

    first->setNext(middle);
    middle->setNext(last);

    std::cout << "using printList()\n";
    LinkedList::printList(first);

    std::cout << "Printing with usual method\n";
    while (first != nullptr) {
        std::cout << first->getValue().c_str() << std::endl;         first = first->getNext();
    }
}

void linkedListNodeDemoWithInt()
{
    auto first =
        std::make_shared<LinkedList::LinkedListNode<int>>(110);
    auto middle =
        std::make_shared<LinkedList::LinkedListNode<int>>(220);
    auto last =
        std::make_shared<LinkedList::LinkedListNode<int>>(330);

    first->setNext(middle);
    middle->setNext(last);

    LinkedList::printList(first);
}

void linkedListNodeDemoWithDouble()
{
    auto first =
        std::make_shared<LinkedList::LinkedListNode<double>>(110.256);
    auto middle =
        std::make_shared<LinkedList::LinkedListNode<double>>(220.587);
    auto last =
        std::make_shared<LinkedList::LinkedListNode<double>>(330.778);

    first->setNext(middle);
    middle->setNext(last);

    LinkedList::printList(first);
}

Thus we see that LinkedListNode can be used to hold any types of data other than ints.

The LinkedListNode class as shown above is still an independent node. We had to manually create a node and link them together to form a valid linked list. So we can create a class LinkedList that can hold these nodes, and provide functions for adding to the head or tail of the node chain; counting number of nodes currently present in the list etc.

The LinkedList class encapsulates all of these functionalities and is defined as below:

template<typename T,
         template<typename> typename LinkedListNode = LinkedListNode>
class LinkedList
{
public:
    LinkedList()
        : m_count(0) {}

    ~LinkedList() {}

    void addFirst(T value);

    int getCount() { return m_count;}

private:
    void addFirst(std::shared_ptr<LinkedListNode<T>>& node);

private:
    std::shared_ptr<LinkedListNode<T>> m_head;
    std::shared_ptr<LinkedListNode<T>> m_tail;
    int m_count;
};

template<typename T,
         template<typename> typename LinkedListNode = LinkedListNode>
void LinkedList<T, LinkedListNode>::addFirst(T value)
{
    auto new_node = std::make_shared<LinkedListNode<T>>(value);
    addFirst(new_node);
}

template<typename T,
    template<typename> typename LinkedListNode = LinkedListNode>
void LinkedList<T, LinkedListNode>::addFirst(std::shared_ptr<LinkedListNode<T>>& node)
{
    std::shared_ptr<LinkedListNode<T>> temp = m_head;

    // point head to the new node
    m_head = node;

    // insert rest of the list behind the head
    m_head->setNext(temp);

    m_count++;

    if (m_count == 1) {
        m_tail = m_head;
    }
}

LinkedList class holds the pointer to head and tail node. The method addFirst() creates a new node object of LinkedListNode class and then calls another overloaded method addFirst() which makes the newly added node as the head of the linked list. This is just one example of how we can add a new node to the existing linked list. We could also add a newly inserted node in the tail.

The LinkedList class can be used as shown below:

void linkedListDemo()
{
    auto int_linked_list =
        std::make_shared<LinkedList::LinkedList<int>>();
    int_linked_list->addFirst(10);
    int_linked_list->addFirst(20);
    int_linked_list->addFirst(30);

    std::cout << "Count = " << int_linked_list->getCount();
}
 

As shown above, we created a linked list that can hold int values and added nodes to the list. The addFirst() method takes an integer value and calls another overloaded addFirst() method that then creates an actual node to hold this integer value.

All source codes discussed here are available in my github page.