Ubuntu 13.10: Run-time error while linking against 'libGL.so'

avril 6, 2014

Recently while trying to run a code previously linked with libGL.so, I got the following run-time error:

Inconsistency detected by ld.so: dl-version.c: 224:
 _dl_check_map_versions: Assertion `needed != ((void *)0)' failed!

It seems that the error is linked to a regression in binutils. Here you can find the discussion on the problem and the different workaround. As I'm using the NVIDIA GL driver, my solution was to simply add the option -L/usr/lib/nvidia-319-updates/ during link time.

I hope it might help some.

0

GDB 7.6

novembre 7, 2013

Recently, I was looking for a solution to have nicer print of STL containers with eclipse-cdt in debug mode. It turns out, the problem had already a solution in gdb. And of course eclipse-cdt debug mode is just a basic graphical wrapper around gdb when using the GCC toolchains. So far so good.

However, since the 7.6 version of gdb, python 3 is used to load scripts. So, in order to have pretty printers for STL containers, you have to update the script to the version 3 of python.

Thus I started a project here. This is just a porting from the original version that you may found here. Eventually I may add support for other types, among them, boost ones. A project already exists for the version 1.40 of boost. Currently this project can't work with this new version of gdb. However performing the porting of the code wouldn't be difficult.

0

Troubles with gedit-latex-plugin in Ubuntu 13.10

octobre 23, 2013

With the new version of Ubuntu, the latex plugin written in python 2.7 doesn't work anymore as now, gedit expect plugin being written in python 3. I found the following link that explain the issue : https://bugs.launchpad.net/ubuntu/+source/gedit-latex-plugin/+bug/1203163. The way to fix it is in one of the given link :

https://mail.gnome.org/archives/gedit-list/2013-July/msg00001.html

Once you've downloaded the tar.gz file, you need to install the following library :

sudo apt-get install intltool
sudo apt-get install libgtk-3-dev

Then unpack the tar, and run :

./configure
make
sudo make install

Once done, you're almost complete. If you run gedit you'll get an error because a python command is ill-formed. This is just a print without parenthesis. What you have to do is to modify the python file :

sudo gedit /usr/lib/gedit/plugins/latex/latex/cache.py

Look for the print and you're done !

3

C++ : Only heap allocated object.

juin 15, 2013
Tags:

I was looking for a way of preventing non heap allocation of a class, plus preventing raw pointer allocation. Well as this is not a trivial task, I found a solution quite elegant and much much more simpler. What I've done is preventing calls to destructors like this :

class A
{
private :
    ~A() {}
};

This prevent the destruction of the object and then any use of it. So how enable the destruction for smart pointer ? Quite simple in fact. Smart pointer are templated with a deleter. And by default they use the std::default_delete functor. So to use your object with std::unique_ptr, you just have to add the following :

class A
{
private :
    // Hell ! How can i use A ??
    ~A() {}
    // Oh ! Ok, through std::unique_ptr.
    friend std::default_delete<A>;
}

Yeah it's clean, simple and quite elegant. Plus it enables any one to directly know how to use your class, no need to read the documentation, just read the class declaration.

I love C++.

Now to use it with std::shared_ptr or any kind of smart pointer I suggest you to read this stackoverflow answer. It shows you how to make it, for a general purpose use.

0

C++ : Why std::unique_ptr ?

juin 9, 2013
Tags:

This new smart pointer is a replacement to the old std::auto_ptr which has been marked as deprecated in C++11. So why this one is not sufficient and now mark as deprecated ?

First, auto_ptr can't handle array. So you can't pass to it an allocated array of int. You'll get an undefined behavior which can lead at best to a crash. Finding the error isn't a pain but it's still inconvenient. The second issue is that you can't put them in a std::vector. That's a terrible pain when you would need such a possibility. Because without it, you'll have to use a raw pointer. Thus, you'll brace yourself, hoping your code will not contains anything breaking your oath.  That's so random.

Well now, they may have other reasons too, that i don't know. Feel free to teach me. :-)

0

C++ : About virtual.

juin 8, 2013
Tags:

People often miss-confused about the use of virtual. Once they've declared a function virtual in a class, they'll declare the same way the function for all next sub-classes, because they are convinced they have to. But compiler doesn't need such an effort, this is absolutely not necessary. However it improves readability as class users will know that the function is inherited.

With C++11, it exists now a better way to improve both readability and avoid error/confusion. As all class declare the function virtual, you don't really know where the function is really declared for the first time so you can't be sure this is in this header or in this one as both are virtual. Plus if you do not override the function properly you'll declare silently a new function that wasn't there in any base classes. Which can be quite annoying when debugging. To avoid this, with C++11, you can know declare your function in sub classes as override which perform a compile time check to see if the function does really override something. If not, you'll get your compile error. Let's see with a simple example :

#include <iostream>

using namespace std;

class A
{
public:
    virtual ~A() {}
    virtual void test() { cout << "A" << endl; } 
};

class B : public A
{
public:
    // Old style to improve readability.
    virtual void test() { cout << "B" << endl; }
};

class C : public A
{
public :
    // C++11 style, which also provide an error if you're
    // trying to lie to your compiler. : )
    void test() override { cout << "C" << endl; }
};

int main()
{
    B b;
    C c;

    A & a = b;
    A & a2 = c;

    a.test();
    a2.test();

    return 0;
}

Nice, isn't it ?

0

C++ : A note on precompiled headers.

mai 1, 2013

When trying to use the precompiled headers form of the glm library, I didn't manage to get it work for a while.

My first mistake was that, you need to have the same compiler's flags than the one you'll use for compiling your other .cpp files. As I'm using the Eclipse CDT IDE, I found a convenient way to do that here. But it was still not working, and I was still seeing the messages from glm (activated with the GLM_MESSAGES macro) during the different compilation stages.

And now, I know why. The following situation will break the use of the precompiled header :

// precompiled header
#pragma once

#include <glm/glm.hpp>

Use of the precompiled header in a.hpp :

// a.hpp
#include "precompiled_header.hpp"

// Declares some stuff

Use of the precompiled header through a.hpp inside other.cpp :

// other.cpp
#include "a.hpp"

// Stuff goes in here

And let's say it is the same for others .cpp files. Then in your compiler output ( I was using gcc ) you'll seee for each .cpp file :

...
/usr/local/include/glm/glm.hpp:96:46: note: #pragma message: GLM: Core library included

So clearly it wasn't working at all. The thing is, you need to include directly in the compilation unit file the header that will be precompiled to get it work.

This is a bit strange, you could have thought the compiler would follow a rule like : "I'm including this header, then this header include those header, do I get any precompiled form for those ones ? If No, then i include them and i do this again for that header file."

0

C++ : Why strongly typed parameters are good.

avril 18, 2013

Today, I've been faced to the sad reality of primitives type parameters. They mean nothing for the compiler. Whereas for us, they can have very different meanings. Let me explain. When you're declaring a function like this one :

Date make_date(int day, int year);

You might be tempted to say, that this function is on the first sight quite simple, but look like something is missing. What you'd like to do, is adding an other parameter like "month". So, you do it, and in the same time you think "well, in the function year was computed as the current one, so let's put a default value for it".

Date make_date(int day, int month, int year = current_year());

And here, comes the problem : the compiler does not complain about it.

And that's a shame, because truly you would like to have plenty of mistakes raised here ! All portions of code that were using the previous version of make_date are still working, but does not produce the expected result. Indeed, calling make_date(10,2013) will call make_date(10,2013,2013) and that's not what you wanted. Any check made inside make_date will raise the error, but the error will happen at run-time, not at compile-time. Now consider the following version of the function :

struct Day
{
    explicit Day(int day) : m_day(day) {}
    int m_day;
}

struct Month
{
    explicit Month(int month): m_month(month) {}
    int m_month;
}

struct Year
{
    explicit Year(int year): m_year(year) {}
    int m_year;
}

Date make_date(const Day& day, const Month& month,
               const Year& year = current_year());

First let me explain why constructors use the explicit key word. If you don't put this key word, then the compiler has the right to do implicit conversion and a call like make_date(10,2013) would stay perfectly legal.

What you can see here is that if you do anything that you want on that function, like changing the order of the parameters or removing one, your compiler will complain about it where you are using the function. And that's great, because you'll be able to find all the bug that could happen. Even you could change your mind realize  that any change was a bad idea...

One thing more, before i let you go, as you may have notice in this example you'll have to change the return type parameter of the function current_year(). But what can you do, if you can't perform this change ? Two options :

Date make_date(const Day& day, const Month& month,
               const Year& year = Year(current_year()));

This one has for drawback that you have made a not pretty looking function, but at least it's simple because you just added 6 characters. An other solution is to define a function inside the class Year like this :

struct Year
{
    // As before
    static Year current_year() { return Year(::current_year()); }
}

Then you can rewrite make_date like following which also requires adding 6 characters :

Date make_date(const Day& day, const Month& month,
               const Year& year = Year::current_year());

The main advantage of this solution over the previous one is that you have more flexibility on the default value of this last argument. Any future change to the way you retrieve the current year, by for instance using an other library function, will force you to go inside the file where Year is defined. This is centralized, thus less error prone.

Several Conclusions :

  • First, you might think that you don't need to create all those classes which would pollute you're namespace, you just have to be careful enough by only adding new parameters to the end of you're function. This doesn't work if some day, you'll need to remove an unused parameter. Especially if this person isn't you. Remember, most of the time code is shared between people and if they can do quick and dirty fix, they will.
  • An other solution, different from the present one here, can be to avoid having function with more than 3-4 parameters. It'll be less error prone, plus users will more likely do less mistakes. Personally, this solution appears to me as the best one because it doesn't involve doing any repetitive things but ask you to do a better design. But of course sometimes this is not possible, and you'll have to choose between the most appropriate solution.
0

Développer en C++ pour les programmeurs Java #1

décembre 11, 2012

Ce billet est le premier d'une série sur le langage C++ pour les programmeurs Java. L'objectif est de répondre aux questions que l'on peut se poser en démarrant le langage, sans pour autant être un cours sur le C++. Essentiellement, cette série répondra aux questions que je me suis posé en apprenant le C++. Ces billets sont donc principalement un condensé de bonnes pratiques à prendre en C++ lorsqu'on a un lourd passé Java. :-)

Dans ce billet, nous allons voir les différentes manières de manipuler les variables en C++ versus celles disponibles en Java.

Déclarer ses variables / méthodes de manière appropriée

En java, on a pas le choix. Seule les références régissent les types non primitif. Du coup on ne se pose jamais la question de ce qui est réellement copié puisque, c'est simple, seule les "adresses" le sont avec les références. Ainsi on écrit :

A a = new A();

// Do something with a
doSomething(a);

// I can still do what i want with a

Et un seule objet aura été crée, mis sur la pile, puis passé par référence à la fonction. Rien de particulier n'aura été écrit dans la déclaration de la fonction, c'est normal c'est du Java. Tout cela est bien trivial.

En C++, la lecture du code se doit être plus attentive, je dirais à vue d’œil que l'on a au moins trois solutions au cas précédent qui produisent toutes trois des résultats différents.

void doSomething(A p_a);
...
A a();
...
// Do something with a
doSomething(a);
...
// a hasn't been changed here

Ce cas entraine une copie de la valeur de a, et donc un nouvel objet de type A est créé pour la fonction doSomething(). Si dans le corps de la fonction se trouve un appel d'une méthode sur p_a, à la ligne 7 l'objet contenu par a n'aura pas été modifié par cet appel.
Ce comportement en java n'est pas reproductible puisque l'on travaille uniquement avec des références. Et lorsqu'il s'agit d'un type primitif (ou d'un objet de type String) les opérateurs modifiants le contenus sont ceux contenant "=", que l'on interprète a juste titre comme une modification du contenu de la variable passé et non de l'objet référencé par la variable. Du coup pour un programmeur Java, un objet peut toujours être modifié dans le corps d'un fonction s'il présente une interface le permettant.

Une deuxième solution est d'utiliser un pointeur. On peut par exemple écrire :

void doSomething(A * p_a);
...
A * a = new A();
...
// Do something with a
doSomething(a);
...
// How am i supposed to know if i can still use "a" safely ??

Un problème se pose cependant à la ligne 7. Si la fonction doSomething() effectue par exemple un delete sur a, c'est le crash assuré si a est encore utilisé par la suite. D'autant que la fonction doSomething() ne peut rien y faire. Affecter son paramètre à 0 ne résoudra rien. Car l'adresse du pointeur est copié lors de l'appel a la fonction mais pas la référence sur la variable a qui contiendra toujours la même adresse après l'appel à doSomething().

Ces premiers exemples reposait sur une signature de doSomething où le type du paramètre a été écrit de la même façon que la déclaration de la variable "a". Le premier cas peut s'améliorer grandement en ne suivant pas cette règle avec bien sûr les références du C++.

Pour définir proprement la méthode doSomething, le mieux est d'écrire ceci :

void doSomething(A & a);
...
A a;
...
doSomething(a);
..
// Here a might have been modified by doSomething,
// and still hold a proper object of type A.

De cette façon, on ne crée pas un nouvel objet de type A et l'on évite de se retrouver avec un pointeur fou. Néanmoins on peut aller plus loin qu'en Java. Supposons que l'on veulent savoir à l'avance si la fonction doSomething va modifier notre objet. Dans le précédent code, rien ne permet de le savoir. Par contre en utilisant le mot clé const, rien qu'en lisant la déclaration de doSomething on peut savoir que celle-ci ne modifiera pas le contenu de l'objet de type A :

void doSomething(A const & p_a);

Ici le contenu de doSomething ne peut faire appel qu'à des méthodes présentant le mot clé const à la fin de leur déclaration. Des méthodes qui ne vont donc pas modifier le contenu de notre paramètre. En java ce comportement n'est pas possible car le mot clé final qui peut être placé au paramètre empêche uniquement de faire appel à new dans le corps de la fonction mais laisse le droit au programmeur de doSomething de modifier l'objet comme il l'entend.

Gérer ses ressources

Initialiser sur le tas un pointeur en C++, c'est créer une ressource. Cette ressource a besoin d'être libéré, une fois que l'on a fini de s'en servir. Sinon, on a ce que l'on a appelle communément une fuite de mémoire. Et ça c'est pas bien :-(. Pour gérer ses ressources, le plus simple est d'utiliser le support de C++ pour les constructeurs, les destructeurs et opérateurs de copie. En exploitant le fait qu'une variable est détruite lorsqu'elle devient hors de portée, on peut s'assurer de libérer sa ressource quel que soit la situation :

{
    A a;
}
// a is out of scope, the destructor of a
// has been automatically called here

L'idée de base d'un manager de ressource est donc de faire appel à delete sur le pointeur dans le destructeur. La librairie standard propose std::auto_ptr (ou std::unique_ptr avec C++11) et std::tr1::shared_ptr (ou std::shared_ptr avec C++11). Le premier permet d'avoir qu'un seul manager à la fois sur la ressource. Son fonctionnement étant un peu particulier, regardons de plus près le manager std::tr1::shared_ptr.

 

 

TO BE CONTINUED

0

Canard en 3D

mars 4, 2012

Blender est un logiciel pas très avenant lorsqu'on l'attaque sans tutoriel. Cependant, une fois le logiciel pris en mains, créer des modèles 3D avec devient très plaisant. J'ai commencé il y a quelques mois la réalisation d'un canard. Voici quelques captures d'écrans :

Une fois terminé, les fichiers blender seront disponibles à la fin de cet article.

1