Sep 12

New domain for Qt announced: qt-project.org

Lars has just announced on his blog that the Qt Open Source Project, under the Open Governance, will be moved to a new domain: qt-project.org (don’t bother copy/pasting, there’s nothing there yet). At the official Nokia Qt Blog, Daniel Kihlberg gives us the date for the launch: October 17th.

The moving to a new domain name has always been in the plans. I remember registering a domain when we started discussing Open Governance, in April of last year. That was, of course, before I knew how long it would take to actually get off the ground and that tranferring domains would be a hassle.

This domain, along with all the infrastructure required to run the project, will be owned by a non-profit foundation. It will not be owned by Nokia, nor any other company. This is to be absolutely clear that the project is neutral, independent of its uses by the companies. Lars is also clear in his blog that decision-making is done by the community, following the guidelines that others and I have been talking about for months.

From the launch point forward, we will say “the Qt Project releases version x.y”, or “the Qt Project has decided to do Z”, where we understand “Qt Project” to be the community decision.

What does this mean for other projects using Qt, like KDE and MeeGo (the “downstreams”)? More access to the decision-making, to the inner workings, directing Qt to their needs; learning from Qt’s good and bad, also finding out where Qt isn’t going, so they can go. In fact, this topic was the subject of my my Camp KDE presentation in April.

Both KDE and MeeGo have begun doing that, to some extent. MeeGo’s goals of a Wayland-based installation, with much improved graphics performance, rhymes with Qt’s. MeeGo has been helping drive the Wayland project. KDE, for its part, has begun the “KDE Frameworks” project, to refactor the KDE Libraries from KDE 4 and make them part of the Qt Ecosystem.

I’m glad to be part of all three projects, helping them see and help each other. Shameless plug: alone, I can’t do much, but together we can do a lot. Join us!

Aug 13

We have C++11

And who says Google Plus isn’t a source of news? I’ve just seen two posts linking to Herb Sutter’s blog, entitled:

http://herbsutter.com/2011/08/12/we-have-an-international-standard-c0x-is-unanimously-approved/

So that’s it, ladies and gents. The standard that we’d been calling “C++0x” for some time now has been fully approved, unanimously no less. It now deserves to be called “C++11″, as the tag I’ve been using on this blog. I’ll also use that wording in new blogs I write on the subject. Hopefully soon GCC will also have the -std=c++11 option, replacing the current one.

Or, as someone has suggested in Herb’s blog, we could call it “C++0xB” and claim we were never wrong :-)

Jul 29

Going to the Desktop Summit

Today, I reserved my flights and my hotel to go to Berlin. I’m not presenting anything, but I will be there representing my new employer, discussing KDE 5 and Qt 5, catching up with old friends.

Mandatory link:

See you there.

Jul 27

KDE Community releases 4.7

Kinda weird to blog on Planet KDE about a KDE release, especially when it’s also announced on the Dot, but I’d like to take the opportunity to congratulate everyone who worked on it!

See the full announcement.

Mandatory screenshot leeched off the announcement:

I am, of course, running something close to the 4.7 release. I usually run the master branch from Git, last built a week or two ago.

Jul 25

Table-driven development, meet C++0x

Last week, I blogged about table-driven development without creating relocations in memory. One of the comments I received indicated that the code was hard to read — I concurred, of course, as it is generated code.

Then Olivier looked at it and decided to have a go at making it entirely generated by the compiler, after being inspired by my C++0x initialisation of arrays. He posted another comment on my blog with the link to his code: http://paste.kde.org/100651/.

That was great! Now we could have the no-relocation table: instead of having pointers, we get the compiler to generate the offset table for us. I just didn’t like about two things in his code: one, his code uses a preprocessor macro so the string can be passed twice. The second was the need to write one long string with “\0″ ourselves.

So I decided to give it a go as well. I got most of what I needed, but was stuck on Friday. Talking to João this morning, he helped me solve my last problem — turns out all I needed was to add one &…

Here’s how you’d use this:

static constexpr auto table =
    createStringTable("Hello", "World");
 
int main()
{
    extern void foo(const char*);
    foo(table[0]);
    foo(table[1]);
 
    // if you ever needed, this works too:
    extern void foo(int);
    foo(table.offset(0));
    foo(table.offset(1));
    foo(table.offset(2));
}

And here’s how it’s done (analysis after the break):

// same code as previous blog
template <int...> struct IndexList {};
 
template <typename IndexList, int Right> struct Append;
template <int... Left, int Right> struct Append<IndexList<Left...>, Right>
{ typedef IndexList<Left..., Right> Result; };
 
template <int N> struct Indexes
{
    typedef typename Append<typename Indexes<N - 1>::Result,
                            N - 1>::Result Result;
};
template <> struct Indexes<0> { typedef IndexList<> Result; };
 
template <typename IndexList> struct DataContainer;
template <int... I> struct DataContainer<IndexList<I...> >
{
    enum { N = sizeof...(I) };
    char data[N + 1];
    constexpr inline DataContainer(const char str[N + 1])
        : data({ str[I]... }) {}
 
    constexpr const char *charptr() const { return data; }
};
 
// new code starts here
template <typename... Args> struct StringTableStrings;
template <int N, typename... Tail>
struct StringTableStrings<const char[N], Tail...>
{
    typedef typename Indexes<N - 1>::Result IndexList;
    DataContainer<IndexList> data;
    StringTableStrings<Tail...> tail;
    constexpr StringTableStrings(const char data[N], Tail... t)
        : data(data), tail(t...) {}
 
    constexpr const char *charptr() const { return data.charptr(); }
};
template <int N> struct StringTableStrings<const char [N]>
{
    DataContainer<typename Indexes<N - 1>::Result> data;
    constexpr StringTableStrings(const char data[N]) : data(data) {}
    constexpr const char *charptr() const { return data.charptr(); }
};
 
template <typename... Args> struct StringTableInts;
template <int N, typename... Tail>
struct StringTableInts<const char[N], Tail...>
{
    int index;
    StringTableInts<Tail...> tail;
    constexpr StringTableInts(int previous)
        : index(previous), tail(previous + N) {}
 
    constexpr const int *intptr() const { return &index; }
};
template <> struct StringTableInts<>
{
    int index;
    constexpr StringTableInts(int) : index(-1) {}
};
 
template <typename... Args> struct StringTable
{
    StringTableInts<Args...> intdata;
    StringTableStrings<Args...> stringdata;
    constexpr StringTable(Args... args)
        : intdata(0), stringdata(args...) {}
 
    int offset(int i) const
        { return intdata.intptr()[i]; }
    const char *operator[](int i) const
        { return stringdata.charptr() + offset(i); }
};
 
template<typename... Args> constexpr
StringTable<Args...> createStringTable(Args &... args)
{
    return StringTable<Args...>(args...);
}

Read the rest of this entry »

Jul 21

Qt 4.8 beta 1 released

I’ve just realised that neither Eckhart’s post nor the QtWebKit post were aggregated on either Planet KDE nor Planet MeeGo.

Quoting:

It has been some weeks since we released the Qt 4.8 Technology Preview to the community. The release raised a lot of interest and we have received many comments in response to the Qt 4.8 TP blog.

Today we release the Qt 4.8 Beta. It should be noted it is not yet a final release candidate but it helps us make the quality of the final release even better. It will be available as an online Qt SDK 1.1 update only.

The Qt 4.8 beta1 package contains QtWebKit 2.2 beta1. It also contains the new port QPA (from the project Lighthouse), which brings us partial Wayland support too.

For the impatient, here are the download links:

PS: the Git tag is called just “v4.8.0-beta”, missing the number 1.

Jul 21

Initialising an array with C++0x using constexpr and variadic templates

When I wrote the blog on improving QString further, I said:

If you can, use the following C++0x expression, which is read-only and sharable:

  static const auto s = QStringLiteral("Hello, World\n");

That above actually does work and does produce a read-only and sharable QStringData containing the UTF-16 “Hello, World\n” string. However, what I didn’t say (because I hadn’t realised at the time) was that the actual s variable wasn’t the QStringData, but a pointer to it. As I discussed yesterday, whenever you have an initialised pointer, the compiler must generate a relocation to make it work on Position-Independent libraries.

To do that, we could simply write something like:

  static const auto s = (QConstStringData<13>)
    { /* insert here the other fields */, u"Hello, World\n" };

The other fields are constant and aren’t part of the parameter, so why not use a nice, constexpr constructor? (By the way, I came across this blog on constexpr).

Read the rest of this entry »

Jul 20

Table-driven methods with no relocations

The other day, someone in the qt-interest mailing list posted the link to an article entitled: How to make fewer errors at the stage of code writing, the third part in a series of articles about writing better code. In this particular article, the author ran a static code-checker tool on the Qt source code and found some mistakes.

One of his suggestions to avoid mistakes was to use table-driven methods as a way to avoid mistakes, like the following:

struct {
  QSysInfo::WinVersion; m_ver;
  const char *m_str;
} Table_WinVersionToString[] = {
  { WV_Me,   "WinMe" },
  { WV_95,   "Win95" },
  { WV_98,   "Win98" },
  { WV_NT,   "WinNT" },
  { WV_2000, "Win2000" },
  { WV_2003, "Win2003" },
  { WV_XP,   "WinXP" },
  { WV_VISTA,"WinVista" }
};

Unfortunately, I see two problems with that solution. The first is that it does not prevent the mistake that the author found anymore than the original solution did (the mistake was to test QSysInfo::WV_2000 twice, trying to return “Win2003″ for the second test). A better solution, making this fool-proof, would not use a table, but an array. However, this would require that the values in the QSysInfo::WinVersion were sequential. I’d instead write the code as:

static const char *DOS_based_names[] =
    { 0, "Win32s", "Win95", "Win98", "WinMe" };
static const char *NT_based_names[] =
    { 0, "WinNT", "Win2000", "WinXP", "Win2003", "WinVista", "Win7" };
if (ver & QSysInfo::WV_DOS_based)
    ret = QLatin1String(DOS_based_names[ver]);
else if (ver & QSysInfo::WV_NT_based)
    ret = QLatin1String(NT_based_names[ver >> 4]);

This code above also uses a table-driven method and is more secure against typing mistakes. It could use some extra checks to see if the versions IDs are in the table, if that’s possible to happen by construction. However, it doesn’t solve the second problem: relocations.

Whenever you have an array like the ones above (mine and the article’s author’s) which contain pointers, the array must be initialised in memory before the code is run. Since on libraries on Unix operating systems are Position-independent code, the actual pointer addresses aren’t known at library link time. They are only known once the library is loaded into memory, which means the dynamic linker must “patch up” the memory — that’s a relocation. For more information into what they are, I suggest reading my previous two blogs on relocation and position-independence: Moving code around and Moving code around more easily.

What I want to do here is to avoid having relocations at all. Having no relocations in my table means it can be stored in a read-only, sharable section of memory. With that, we have a faster load time of the library and we use less memory per application loading the library. So how can we have a table containing strings without relocations?

Back in 2006, when I wrote QtDBus, I faced a similar problem for the QDBusError class: I needed a way to map the enum containing the error codes to the error names. Inspired by the output from moc, the solution I found was to write a small Perl script that generated one very long string containing NULs (“\0″) and an array of indices into that table.

So instead of having a table like:

static const char *DOS_based_names[] =
    { 0, "Win32s", "Win95", "Win98", "WinMe" };

We’d instead have:

static const char DOS_based_names_string[] =
    "\0"
    "Win32s\0"
    "Win95\0"
    "Win98\0"
    "WinMe\0"
    "\0";
static const int DOS_based_names_indices[] = {
       0,    1,    8,   14,   20,   -1
};
ret = QLatin1String(DOS_based_names_string + DOS_based_names_indices[ver]);

The code above generates no relocations in the shared library and both the string and the integers can be safely stored in the .rodata section. Depending on the architecture, the amount of extra code can be trivial or not (see the end of the post for some assembly listings).

I found this technique so useful I applied it in many places in KDE. I even added a script to kdesdk called generate_string_table.pl that generate string tables. In fact, I generated the table above by running:

perl generate_string_table.pl DOS_based_names <<<'
Win32s
Win95
Win98
WinMe'

The script works fine for arrays, but the principle is the same for an associative table. Instead of creating an array of ints, you’d create an array of structs mapping the original type to the offset in the string. Writing such a script is left as an exercise for the reader.

Read the rest of this entry »

Jul 17

QString improved

On my birthday, I blogged about how I’d like QString to support proper UTF-8 strings and be much easier to use. The code that I said would be my preferred would be:

    QString s = u"Résumé"q;

Recently, in Qt 5.0 we have begun to make steps to reach that. Most of the work was done by Lars Knoll, but since he is on vacation right now, I’ll take the opportunity to explain it all. (Also, many thanks to Olivier Goffart for helping with reviewing)

Read the rest of this entry »

Jul 17

New blog website

After 4 years blogging on the Qt Labs, it’s time to move on. This is a familiar WordPress installation, but I still need to tweak it a bit. For example, I need to figure out how to configure proper syntax highlighting. Any hints?

» Newer posts

Page optimized by WP Minify WordPress Plugin