Le 3ème argument d'un QObject::connect (le contexte) peut être très utile pour éviter les crash en cas de destruction du pointeur visé dans cet argument. Ou en cas de connexion inter-threads.
Voilà longtemps que je n'avais rien publié sur mon blog "30 minutes par jour". Je pourrai le renommer "30 minutes par an" ;-)
When adding some files to INSTALLS, they are stripped if they are excecutables.
To avoid using strip, you can update "QMAKE_STRIP" variable and force stripping executables one by one using ".extra":
target.extra = strip $${DESTDIR}/$(TARGET)
QMAKE_STRIP = echo # Avoid striping unwanted files (which will not work)
applibs.files = $${DESTDIR}/*.so*
applibs.path = $$EXPORT_LIBPATH
INSTALLS += applibs
Un autre post sur les QThread.
Hier, j'ai releasé la v0.2.6 de Qompoter, a C++/Qt dependency manager. Outre les améliorations apportées au truc (recherche récursive des paquets, numéros de versions flous du genre v1.*, recherche des paquets dans Inqlude), cela m'a aussi permis de découvrir les scripts d'auto-complémetion Bash ! Et je surkiffe taper qompoter tab tab
et voir la liste des actions possibles apparaître "install export inqlude jsong". C'est beau Linux.
Qompoter a atteint un niveau de maturité suffisant pour les petits projets, alors n'hésitez pas ! Vos retours sont les bienvenues.
Très pratique le fichier .qmake.conf.
Pour me rappeler, je m'essai aux résumés.
* RVO = return-value optimization
MyData myFunction() {
return MyData(); // Create and return unnamed obj
}
MyData abc = myFunction();
With RVO, the C++ standard allows the compiler to skip the creation of the temporary, treating both object instances—the one inside the function and the one assigned to the variable outside the function—as the same. This usually goes under the name of copy elision. But what is elided here is the temporary and the copy.
MyData myFunction() {
MyData result; // Declare return val in ONE place
if (doing_something) {
return result; // Return same val everywhere
}
// Doing something else
return result; // Return same val everywhere
}
MyData abc = myFunction();
Named Return Value Optimization is similar but it allows the compiler to eliminate not just rvalues (temporaries), but lvalues (local variables), too, under certain conditions.
But many compilers are actualy failing to apply NRVO with the following code:
MyData myFunction() {
if (doing_something)
return MyData(); // RVO expected
MyData result;
// ...
return result; // NRVO expected
}
MyData abc = myFunction();
So previous example has to be preferred.
Surprisingly, don’t use "out-parameters" but prefer "return-by-value", even if it implies creating a small struct in order to return multiple values. I will check that, because it seems strange to me.
“out” parameter pointers force a modern compiler to avoid certain optimisations when calling non-inlined functions.
Prefer:
struct fractional_parts {
int numerator;
int denominator;
};
fractional_parts convertToFraction(double val) {
int numerator = /*calculation */ ;
int denominator = /*calculation */ ;
return {numerator, denominator}; // C++11 braced initialisation -> RVO
}
auto parts = convertToFraction(val);
use(parts.nominator);
use(parts.denominator);
than:
void convertToFraction(double val, int &numerator, int &denominator) {
numerator = /*calculation */ ;
denominator = /*calculation */ ;
}
int numerator, denominator;
convertToFraction(val, numerator, denominator); // or was it "denominator, nominator"?
use(numerator);
use(denominator);
Prefer:
template <class T>
complex<T> &complex<T>;::operator*=(const complex<T> &a) {
T a_real = a.real, a_imag = a.imag;
T t_real = real, t_imag = imag; // t == this
real = t_real * a_real – t_imag * a_imag;
imag = t_real * a_imag + t_imag * a_real;
return *this;
}
than:
template <class T>
complex<T> &complex<T>;::operator*=(const complex<T> &a) {
real = real * a.real – imag * a.imag;
imag = real * a.imag + imag * a.real;
return *this;
}
It seems the example is too simple to really understand the benefits. I do not want to make my code more complex for such a simple case... I do not like this advice.
Due to the CPU caches mechanisms (blocks of 64-byte), it is propose to organise member variables in a class as follow:
Why not...
Oui, un framework Web en Qt.
For our purposes, we will define "C++ Type Constraint" in the following way:
A C++ Template will have one or more type arguments. The template may require that each argument fullfill more or more conditions in order for the template to compile without error. These requirements are called Type Constraints or Type Requirements.
C++ literature and documentation use the word Concept for this purpose. In fact, this usage of the word Concept is one of the reasons that the subject has been so confusing. Another reason is that it is really only necessary to understand Concepts when writing a templated library. Since very few programmers actually write such code, very few people actually use this idea and hence are unfamilar with it. Our term Type Constraint is exactly equivalent to the C++ term Concept. Either one can be substituted for the other without loss of meaning.
Un des trucs qui me fascine en C++, c'est que sa communauté contient beaucoup de personnes qui semblent fichtrement intelligentes et qui se posent des problèmes et des questions invraisemblable.
On retrouve ça ailleurs, comme une partie de la communauté Javascript par exemple (dingue), mais pas partout.
Un autre compilateur C++ online.
Pour le coup, cet article n'ayant pas pour but d'expliquer RAII l'explique beaucoup mieux que d'autres.
Franchement, le Web, c'est génial !
Et GCC, Qt, C++, Linux aussi.
Quelques infos complémentaires :
Il va me falloir un peu de temps pour acquérir les réflexes C++11.
Premiers essais de CMake aujourd'hui :-) Depuis le temps que je souhaitais m'y frotter.
J'aimerai bien que mon petit projet Qompoter (https://github.com/Fylhan/qompoter) sache faire du qmake et du CMake
Jusqu'à aujourd'hui, j'avais un petit script qui me générait tout ce qui va bien pour un enum C++ (avec des binding Qt). Mais Q_ENUM fait ça tout seul !
Cette explication des sémaphores / mutex et autre semblent très intéressantes.
Voilà qui clarifie bien les choses.
La conversion de rvalue en lvalue est assez tordue :
"This doesn't mean that lvalues can't be produced from rvalues by more explicit means. For example, the unary '' (dereference) operator takes an rvalue argument but produces an lvalue as a result. Consider this valid code:
p = &arr[0];
int arr[] = {1, 2};
int
(p + 1) = 10; // OK: p + 1 is an rvalue, but (p + 1) is an lvalue
Conversely, the unary address-of operator '&' takes an lvalue argument and produces an rvalue:
"
int var = 10;
int bad_addr = &(var + 1); // ERROR: lvalue required as unary '&' operand
int addr = &var; // OK: var is an lvalue
&var = 40; // ERROR: lvalue required as left operand
// of assignment
Ces deux derniers point ne sont pas vrais en Qt si c'est dans la définition d'un signal ou d'un slot. Qmake génère un moc_.cpp à partir du .h, et il a besoin des définitions des paramètres.
Cette bibliothèque Qt pour lancer un serveur ou un client HTTP semble idéale (licence MIT). Plus aboutie que QHttpServer (https://github.com/nikhilm/qhttpserver, licence MIT aussi).
ça fait plusieurs développeurs Node.js que je vois aussi faire du C++ avec beaucoup de talent. C'est bien les gars ;-)
Premier article d'une série sur les tests en Qt / C++.
Le site du concepteur de C++. Pas mal de ressources.
P.S : oui, j'avais quelques bookmarks à trier dans ma barre personnelle de Firefox :-D
Inqlude: http://inqlude.org/
Qt Apps : http://qt-apps.org/
Site officiel : http://qt-project.org/wiki/Category:Add-ons
Sur Github : https://github.com/search?nwo=0TheFox0%2FOpenChart&p=7&q=qt+plugin&ref=cmdform&search_target=global&type=Repositories
Le concept de lock-free programming est vraiment intéressant : empêcher les possibilités de blocages, ou les erreurs lors de l'utilisation d'une mémoire partagée entre plusieurs threads. L'idée étant de ne pas utiliser de mutex, et soit de séquentialiser l'accès à la mémoire partagée, soit d'utiliser des petites opérations atomiques (qui seront exécutée sans interruptions).
Il n'est pas tellement vraisemblable de créer un gros programme lock-free, l'idée est plutôt de rester pragmatique et de faire interagir plusieurs parties lock-free entres elles.
Le gain en performance par rapport à des mutex est assez flagrant. Et c'est à mettre en place pour coder efficacement sur du multi-processeur. Mais les compétences pour une mise en œuvre correcte sont aussi plus grandes.
"So keep mutexes, unless you have a lot of lock contention or are looking for a challenge."
Une autre ressource sur le sujet :
http://woboq.com/blog/introduction-to-lockfree-programming.html
Et comment gérer des opérations atomiques en Qt :
http://qt-project.org/doc/qt-5/qatomicint.html
Une définition assez claire de "thread-safe" et "reentrant".
Ok, je crois que je vais me coltiner ça.
Apparement, voici la liste des DLL nécessaires pour faire tourner un programme sous Qt5 :
Des bibliothèques (et exemples d'applications) sous Qt pouvant s'avérer utiles à l'occasion.
En C++, une classe est automatiquement amie d'elle même. Ce qui explique l'on puisse appeler un objet privée de la classe dans le constructeur de copie. Ahhhhh !!! Je comprends mieux.
Exemple :
class MyClass {
public:
MyCLass() : myVar(0) {}
MyClass(const MyClass& parent) {
myVar = parent.myVar; // will work and is possible
// myVar = parent.myVar(); // won't work like this. myVar() has to be "int myVar() const;"
}
int myVar() { return myVar_; }
private:
int myVar_;
};
Arg, pour connecter un QObject qui a été forward declared (class MyQObject dans le .h de l'utilisateur), il ne faut pas oublier d'inclure réellement le .h du QObject (dans le .cpp de l'utilisateur) pour éviter l'erreur à la compile : "No matching function for call to connect".
CppCheck a l'air d'être un utile pratique pour analyser statiquement du code C++. A intégrer à un Jenkins / Hudson, avec un nightly build des tests unitaires (+ tests d'intégrations automatisés ?) voilà qui serait pratique...
Ne jamais, JAMAIS (jamais !) créer la méthode "connect" dans un QObject en Qt !
Je comprends enfin pourquoi ce fichu signal ne voulait pas se connecter à ce sacré slot ! Eh bah voilà : une méthode "connect" (censée, je cite, "Start the connection to the remote server") qui surcharge bien malencontreusement la méthode "QObject::connect" ce qui nous donne "error : no matching function for call to 'MyGreatObject::connect(AnOtherObject&, const char, MyGreatObject const, const char)'".
C'est bête hein ?
Rah!
QString de Qt : "Tant que l'objet est copié, passé en paramètre, .... l'objet n'est pas dupliqué (tous les objets pointes vers le même espace mémoire)."
Eh je ne savais pas que QString était un QSharedDataPointer ! Bien !
Pourquoi n'est-ce pas le cas des String en Java ? Sur un gros projet auquel je participe, des devs se sont "amusés" à concaténer crapuleusement des String Java. Et hop, une nouvelle instance de String à chaque fois ! La mémoire globale le ressent... et franchement, on n'avait pas besoin de ça !
Mon point de vue sur l'injection de dépendances en C++ : à la main ! Parce que pour l'instance, il n'y a pas de container suffisamment léger et non-intrusif.
J'utilise assez souvent LINE ou FILE en PHP pour récupérer respectivement le numéro de la ligne courante, et le nom du fichier courant, et je savais que cela venait du C. Je n'avais jamais remarqué que ces macros existent donc aussi en C++. Pratique pour déboguer !
Voilà qui répond bien à mes questions quant à la modification de paramètres d'une méthode en Java.
Ainsi que ces deux topics :
http://stackoverflow.com/questions/5607773/change-a-functions-arguments-values
http://stackoverflow.com/questions/40480/is-java-pass-by-reference
Ahahah !
Aside: Someone might say, “but can’t someone still write load_widget(some_id).release()?” Of course they can, if they’re pathological; the correct answer is, “don’t do that.” Remember, our concern is to protect against Murphy, not Machiavelli—against bugs and mistakes, not deliberate crimes—and such pathological abuses fall into the latter category.
A part ça, "modern C++" est vraiment puissant ! Je reconnais que pour l'instant j'utilise plutôt Qt et je reste très très loin des "smart pointers". De voir qu'il est possible d'utiliser quelque chose du type "optional