Ivan Čukić

API Design Part 2: Impact on the safety

Continuing on the topics I talked about at this year’s aKademy conference.

Most of the things I want to write here are not new to people who are immersed in C++ and follow the books/presentations by Alexandrescu, Sutter, and others. But, I’ve found that in our Qt-sub-culture, it is often not the case.

Qt is very good at hiding the ugly parts of C++, but at the same time, it sometimes hides too much.

Memory safety

One of the first things you learn in Qt is about the object trees and ownership where the parent obect conviniently destroys its children on its destruction.

IMO, this is one of the nicest features of Qt. But, sometimes, it tends to provide a sense of false security. As trivial example, imagine the following:

QThread *thread = new QThreadDerivedClass(this);
thread->start();

It looks nice – we are creating a new object, we pass it a parent (this), so we do not need to worry about its destruction ourselves. The issue is that the parent is often a long-lived object like a QCoreApplication or a main window. This tends to end up in the thread object not being destroyed until the application has been terminated.

Now imagine that the above object is an image cache, and you’ll have a quite substantial memory leak.

The parent-child ownership is a silver bullet in a lot of cases, but not all.

What does a pointer mean?

So, lets return to the topic at hand – API design. One of the biggest problems when using a new library is what the following declaration means:

SomeType * someMethod();

Namely, the question here is what does the ‘SomeType *’ mean. It can mean quite a few things:

  • (static) singleton instance
  • should be disposed by the user
  • creator-owned, creator disposes of it
  • an optional value? (for example, parsing a number from a string could return a null if parsing failed)
  • position in an array? (this one is rarely used nowadays, we have iterators for that case)

The problem here is deducing who owns the returned object, and are we guaranteed to get a non-null result at all. It can not be deduced without reading the documentation, and it could and should be.

1. Singletons

Since a singleton should be always present, there is really no point in making it a pointer at all. Implementing a proper singleton should be as easy as:

SomeType & instance() 
{
    static SomeType s_instance;
    return s_instance;
}

It is thread-safe (in C++11), its declaration clearly states that it returns a non-null object, and an object with a long lifetime.

2. Factories

The next are the factory functions that return an instance of the object whose owner should be the callee, and the callee is responsible for its destruction:

std::unique_ptr<SomeType> createObject(...);

Even if the callee forgets to save the returned value, nothing will be leaked.

3. Caches, ref-counted singletons, etc.

When we have a function that returns something that can be destroyed at any time, or that should be destroyed only after everyone stops using it, we can simply write

std::shared_ptr<SomeType> getObject(...);
// or
std::weak_ptr<SomeType> getObject(...);

The first one tells the callee that the object will exist for as long as he wants to use it, but without the guarantee that it will be destroyed immediately after.

While the later says that it has been given an object that could go away at any point in time.

4. Optional result values

The last use-case is the most problematic one. Not because it has not been solved, but rather because the necessary class has not yet been provided in C++.

When it becomes the part of the standard, it will look something like this:

std::optional<SomeType> parseTheType(...);

For the time being, you could use boost::optional, pair<bool, SomeType> and similar.

If you wanted to give the failure error as well, without resorting to throwing exceptions all over the place, my advice is to go and watch Alexandrescu’s talk on “Systematic error handling in C++”.

Exception safety

Now, after we saw what can be done to the API to make the user’s life easier when it comes to memory management, just a very short note about the exception safety.

There is a reason why std::stack does not have a method pop that returns a value, but has the separated top and pop. This is, again, one of the things that should be known to most c++ developers, yet sometimes you can even find some c++ book authors that take jabs at the standard committee for making it that way, and not going for the more convenient API.

I suggest everyone to look at some writings about this – the issue itself gives a nice overview of things to watch out for when designing API which should behave well in the exception-enabled environment.

Build profiles addon script for kdesrc-build

I’ve been keeping a set of scripts to keep parallel builds of a few projects, to be able to test whether everything behaves well on older compilers. It is also nice to compile things with clang while developing since it usually provides nicer error messages compared to gcc, even if might be slower or generate slower code.

The main problem is that the setup was not really scalable. Adding new build profiles, or projects was not as easy as it ought to be.

Enter kdesrc-build-extra

kdesrc-build-extra is a simple tool that creates profile-based alternative builds to those created by kdesrc-build. It does not do it for all projects, but only for those that you choose.

ksbextra

It allows you to create a few profiles, and specify which projects you want built with each of them. So, for example, you can keep parallel builds of plasma-workspace with gcc 4.5 and the latest clang, while having a static checker like clang-analyze for plasma-framework.

The example configuration file comes with the program. The format is the same as the one used by kdesrc-buildrc, just with a few custom fields.

This is one of the profiles from the provided example configuration file:

# Build profile for building with the clang compiler
build-profile clang-build

  # Prefix to use for building this profile
  build-dir    /opt/kf5/build-clang/

  # [optional] Where to install the binaries from this profile
  # install-dir /opt/kf5/usr-clang/

  # C++ compiler executable
  cxx-compiler /usr/bin/clang++

  # C compiler executable
  c-compiler   /usr/bin/clang

  # Which options to remove from the kdesrc-build setup
  # when building this profile.
  # Parameters covered by the above setting values are
  # automatically removed.
  cmake-options-remove -DUSE_COMPILER_HIDDEN_VISIBILITY \
                       -DKDE4_BUILD_TESTS \
                       -DBUILD_TESTING

  # What should we add to the parameter list?
  cmake-options-add    -DUSE_COMPILER_HIDDEN_VISIBILITY=0

  # Which projects do you want to build using this profile
  projects kactivities plasma-framework

end build-profile

Installation

Now comes a bit weird part. Since these kinds of scripts in KDE tend to cover all programming languages in existence – perl, ruby, python and similar, I decided to go over the edge and do this in Haskell.

Thanks to Haskell’s package manager, the installation is quite simple.

cabal update
cabal install kdesrc-build-extra
cp ~/.cabal/bin/kdesrc-build-extra /path/to/your/kf5/sources

(you just need to install cabal and ghc before doing that)

Usage

Copy the kdesrc-build-extrarc-example file into the KF5 sources directory, edit it to fit your setup, and that is it.

ottens.js

Introducing ottens.js inspired by Kevin’s great talk at aKademy script that does to your web page what should have been done a long time ago. Just call the function when your page has been loaded.

function ottensize() {
    var html = document.body.innerHTML;
    html = html.replace('hacking', 'crafting');
    html = html.replace('hacked', 'crafted');

    document.body.innerHTML = html;
}

… and they pop up on your desktop

If you like to keep your project-related files on your desktop for easy access, you might have kept links to them in different folders which you placed in a folder view.

Now, it is much easier, just link them to the activity they belong to, and set the folder view to display it.

folderview

Linking files to activities

News from the Society for Putting Things on Top of Other Things:

Another feature has returned. This time with less issues and much more speed.

Linking

(yes, activities do need a new icon :) )

Plugins for KAMD and system settings module

All plugins from the old activity manager are ported to the new version.

This means that one of the most requested features is coming back – you will be able to set custom keyboard shortcuts for individual activities as soon as Plasma 5.1 comes out.

Also, the system settings module for configuring activities is back to its full glory (modulo one little visual issue).

kcm_1

Choosing the plugins

Per-activity favourites in Kickoff

I’ve become overly lazy when writing blog posts is concerned. Maybe it is because I’m again working on the user-visible features, and it is much easier to just post a screen-shot or a screen-cast, than to actually write anything meaningful.

Per-Activity Favourites

It also gives the audience a chance to ask ‘does this mean that plasma will have …’ which sometimes brings wonderful ideas to life.

A screencast of the activity switcher in Plasma 5.1

Plasma 5.0 has been released today, but the work does not stop with it.

We have been preparing features planned for 5.1 (and later) for some time now. The new activity switcher is one of them, and it is coming along nicely. It is already much more polished and optimized than the one available in 5.0.

If you want to see it in action, just check out the new screen-cast (I recommend watching it in 720p, it looks much nicer):

Open the video on YouTube >

It shows some old features, but also a few of the new ones.

Be seeing you!

Just a teaser

Activity Window Management

The future of activity switching

I have returned to the colourful world of UI (still refusing to say UX :) ) development.

The new pretty thing that is taking away my time is the activity switcher which got a rather big revamp for the next release of Plasma.

Activity Switching in Plasma After Next

Apart from the new UI, it got a few usability improvements, namely full keyboard navigation. You are able to filter, navigate and switch activities without touching your mouse.

Meta+Tab activity switching

Unfortunately, not all is great – the Meta+Tab shortcuts for switching activities are not going to be enabled for the first release, they will have to wait for the one after.

What will that look like?

As you can see in the screen-cast, the Meta+Tab will (unlike old Plasma) have a visual feedback – it will show the switcher until you release the Meta key. Similarly to how Alt+Tab for window switching works.

Per activity global shortcuts

The second thing that will need to wait is the port of the global shortcuts plugin by Makis Marimpis. I expect it to be present in the same release as Meta+Tab.