IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
logo

FAQ C++Consultez toutes les FAQ

Nombre d'auteurs : 34, nombre de questions : 368, derni�re mise � jour : 14 novembre 2021  Ajouter une question

 

Cette FAQ a �t� r�alis�e � partir des questions fr�quemment pos�es sur les forums de http://www.developpez.com et de l'exp�rience personnelle des auteurs.

Je tiens � souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose sont correctes ; les auteurs font le maximum, mais l'erreur est humaine. Cette FAQ ne pr�tend pas non plus �tre compl�te. Si vous trouvez une erreur ou si vous souhaitez devenir r�dacteur, lisez ceci.

Sur ce, nous vous souhaitons une bonne lecture.

SommaireDivers (9)
pr�c�dent sommaire suivant
 

La fonction standard std::system() d�finie dans <cstdlib> permet d'ex�cuter la commande qui lui est fournie en param�tre au moyen de l'interpr�teur de commande du syst�me d'exploitation.
Son comportement est donc sp�cifique � chaque OS.

Code c++ : S�lectionner tout
1
2
3
4
5
6
7
8
9
10
#include <cstdlib>  
  
int main()  
{  
    // ex�cute la commande syst�me "dir"  
    // le texte affich� d�pend de l'OS  
    std::system( "dir" );  
    // ex�cute le programme "toto.exe"  
    std::system( "toto.exe" );  
}
L'appel � cette fonction ne rend pas la main tant que la commande n'a pas termin� son ex�cution.
Si vous souhaitez un comportement diff�rent (que la fonction rende la main imm�diatement, qu'une console ne soit pas cr��e, rediriger les flux standard), il faut vous tourner vers une solution sp�cifique � votre syst�me d'exploitation.
Voir les fonctions CreateProcess / ShellExecute[Ex] sous Windows, et les fonctions de type exec*() et spawn() d�finies dans les headers <unistd.h> / <process.h> pour les syst�mes UNIX/POSIX (Notez qu'elles sont aussi disponibles avec un underscore pr�fix� � leur nom ( _exec et _spawn sous Visual C++).

Mis � jour le 18 avril 2005 Aurelien.Regat-Barrel

Cette question se destine tout d'abord aux responsables non techniques et au personnel des ressources humaines qui essaient de faire un travail de bonne qualit� quand ils interviewent des candidats d�veloppeurs C++. Si vous �tes un programmeur C++ sur le point d'�tre interview�, et que vous consultez cette FAQ en esp�rant savoir � l'avance quelles questions vont vous �tre pos�es de fa�on � ne pas devoir apprendre r�ellement le C++, honte � vous. Prenez le temps de devenir un d�veloppeur comp�tent et vous n'aurez pas besoin d'essayer de tricher.

Pour revenir aux non techniciens et au personnel des ressources humaines : il est �vident que vous �tes parfaitement qualifi�s pour juger si un candidat a un profil correspondant � la culture de votre entreprise. Cependant, il y a assez de charlatans, de menteurs et de frimeurs pour que vous ayez besoin de faire �quipe avec quelqu'un qui est techniquement comp�tent pour s'assurer que le candidat ait le niveau technique ad�quat. Assez de soci�t�s ont souffert d'avoir engag� des gens sympathiques mais incomp�tents, des gens globalement incomp�tents malgr� le fait qu'ils connaissent les r�ponses � quelques questions tr�s pointues. La seule fa�on de d�masquer les menteurs et les frimeurs est d'avoir � vos cot�s une personne capable de poser des questions techniques pointues. Il n'y a aucun espoir que vous y arriviez par vous-m�me. M�me si je vous donnais une s�rie de questions pi�ges, elles ne vous permettraient pas de d�masquer ces personnes.

Votre partenaire technique n'a pas besoin d'�tre qualifi� (et bien souvent, il ne l'est pas) pour juger la personnalit� du candidat, donc, par piti�, n'oubliez pas que vous �tes le seul juge au final. Mais ne pensez pas que vous pouvez poser une demi-douzaine de questions sur le C++ et avoir la moindre chance de savoir si le candidat sait de quoi il parle, du moins d'un point de vue technique.

Par contre, si vous avez un niveau technique suffisant pour lire cette FAQ, vous pouvez y piocher quantit� de bonnes questions pour une interview. La FAQ contient bon nombre de choses permettant de s�parer le bon grain de l'ivraie. La FAQ se concentre sur ce que les programmeurs doivent faire, plut�t que d'essayer de voir ce que le compilateur leur laisse faire. Il y a des choses en C++ qu'il est possible de faire mais qu'il vaut mieux �viter. La FAQ sert � faire le tri l�-dedans.

Mis � jour le 10 f�vrier 2004 Cline

Voici quelques astuces pour r�duire les temps de compilation, qui peuvent parfois se compter en minutes voire en heures sur des projets de taille cons�quente.

  1. Utiliser les d�clarations anticip�es
    Si dans un en-t�te vous ne d�clarez qu'un pointeur ou une r�f�rence sur une classe, alors vous n'avez pas besoin d'inclure son en-t�te : une d�claration anticip�e suffit.

    MaClasse.h

    Code c++ : S�lectionner tout
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Classe1; // pas d'inclusion de "Classe1.h" 
    class Classe2; // pas d'inclusion de "Classe2.h" 
      
    class MaClasse 
    { 
        void Something(const Classe1& c); 
      
        Classe2* c2; 
    };
    MaClasse.cpp

    Code c++ : S�lectionner tout
    1
    2
    3
    4
    5
    6
    7
    8
    #include "Classe1.h" 
    #include "Classe2.h" 
      
    void MaClasse::Something(const Classe1& c) 
    { 
        // Ici on peut acc�der aux membres de Classe1 et Classe2, 
        // on a inclus leurs en-t�tes 
    }
    Ainsi lorsque Classe1 ou Classe2 sera modifi�e, seul MaClasse.cpp sera recompil�. Sans cette astuce, vous auriez d� recompiler (inutilement) tous les fichiers incluant MaClasse.h. L'�limination des d�pendances inutiles est essentielle pour am�liorer les temps de compilation.
  2. Utiliser l'idiome enveloppe-lettre, appel� aussi Pimpl (Private Implementation)
    Le principe de cet idiome est de s�parer l'interface publique d'une classe de son impl�mentation.

    MaClasse.h (interface)

    Code c++ : S�lectionner tout
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class MaClasseImpl; 
      
    class MaClasse 
    { 
    public : 
      
        void Set(int); 
        int Get() const; 
      
    private : 
      
        MaClasseImpl* pImpl; 
    };
    MaClasse.cpp

    Code c++ : S�lectionner tout
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include "MaClasseImpl.h" 
      
    void MaClasse::Set(int x) 
    { 
        pImpl->Set(x); 
    } 
      
    int MaClasse::Get() const 
    { 
        return pImpl->Get(); 
    }
    MaClasseImpl.h (impl�mentation)

    Code c++ : S�lectionner tout
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class MaClasseImpl 
    { 
    public : 
      
        void Set(int); 
        int Get() const; 
      
    private : 
      
        int val; 
    };
    MaClasseImpl.cpp

    Code c++ : S�lectionner tout
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include "MaClasseImpl.h" 
      
    void MaClasseImpl::Set(int x) 
    { 
        val = x; 
    } 
      
    int MaClasseImpl::Get() const 
    { 
        return val; 
    }
    Ainsi, seule une modification de l'interface de MaClasse entra�nera une recompilation des fichiers qui en d�pendent. Un changement dans son impl�mentation n'entra�nera la recompilation que de deux fichiers au maximum : MaClasse.cpp et MaClasseImpl.cpp.
    Comme vous le voyez dans cet exemple, MaClasse est ici limit�e � son interface publique, toutes ses donn�es priv�es et prot�g�es sont cach�es dans MaClasseImpl. C'est un autre avantage de ce proc�d� : en plus de r�duire les d�pendances et d'acc�l�rer la compilation, l'idiome pimpl permet de ne rendre visible pour les clients d'une classe que son interface publique.

    Pour plus de d�tails sur l'idiome pimpl, nous vous invitons � consulter ces liens tir�s de GOTW :
  3. Utiliser les en-t�tes pr�compil�s
    En plus des techniques cit�es ci-dessus, certains environnements de d�veloppement comme VC++ et BCB proposent d'utiliser un en-t�te pr�compil�. Pour en tirer partie il faut :
    • Activer son utilisation dans les options du projet.
    • Inclure dans l'en-t�te pr�compil� (par d�faut, stdafx.h sous VC++) tous les en-t�tes que vous ne modifierez pas ou peu souvent (en-t�tes standards, de biblioth�ques externes�).
    • Inclure l'en-t�te pr�compil� dans toutes les unit�s de traduction (les .cpp) du projet.

    Si vous y incluez un en-t�te subissant des modifications fr�quentes cela aura l'effet inverse : � chaque modification de celui-ci vous aurez droit � une recompilation compl�te.

Mis � jour le 17 octobre 2005 Laurent Gomila

C'est tout � fait normal. Cela est d� au codage interne des flottants en m�moire (selon la norme IEEE 754). Ces impr�cisions deviennent d'autant plus g�nantes qu'elles s'accumulent en m�me temps que les op�rations que vous effectuez sur vos nombres ; ainsi il est tout � fait possible d'obtenir des nombres tr�s �loign�s des r�sultats th�oriques.

Il n'existe pas de solution miracle, cependant vous pouvez tout de m�me trouver un compromis selon vos besoins :

-> Vous avez besoin d'une pr�cision exacte (gestion de comptes ou autres applications mon�taires) : utilisez plut�t ce que l'on appelle les nombres en virgule fixe, qui, g�n�ralement cod�s sous forme d'entiers, ne souffrent pas de ces impr�cisions. Le C++ ne dispose pas en standard de types en virgule fixe, mais vous pourrez facilement trouver des classes ou des biblioth�ques toutes faites, voire construire la v�tre.

-> Vous voulez tenir compte des impr�cisions dans vos calculs : utilisez un epsilon (nombre tr�s petit) lors de vos tests de comparaison. Typiquement, l'espilon choisi d�pend de votre application et des grandeurs manipul�es. Un point de d�part est l'espilon d�fini dans la biblioth�que standard (std::numeric_limits<float>::epsilon() pour les float par exemple), qui d�finit le plus petit flottant tel que 1 + espilon > 1. Ainsi vos comparaisons deviennent :

Code c++ : S�lectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <cmath> // pour std::abs 
#include <limits> // pour std::numeric_limits 
  
using namespace std; 
  
float f1 = 0.1f; 
float f2 = 1.1f; 
float f3 = f2 - f1; 
  
// Version incorrecte ne tenant pas compte des impr�cisions 
if (f3 == 1.0f) 
{ 
    // Pratiquement jamais vrai ! 
} 
  
// Version correcte tenant compte des impr�cisions 
// err est une variable choisie en fonction de l'erreur autoris�e 
if (abs(f3 - 1.0f) <= err * max(abs(f3), abs(1.0f)) * numeric_limits<float>::epsilon()) 
{ 
    // Ok 
}

Mis � jour le 3 f�vrier 2007 Jean-Marc.Bourguet Laurent Gomila

Lorsque l'on veut �crire du code portable, il est parfois n�cessaire d'utiliser la compilation conditionnelle, c'est-�-dire compiler tel ou tel code selon la plateforme sur laquelle on se trouve.

Par exemple, voici un code qui sera capable de compiler correctement � la fois sous Windows et sous Unix :

Code c++ : S�lectionner tout
1
2
3
4
5
6
7
8
#if defined (linux) 
    // Code sp�cifique � Linux 
#elif defined (_WIN32) 
    // Code sp�cifique � Windows 
#else 
    // Plateforme non g�r�e, on peut par exemple placer une erreur de compilation 
    #error Plateforme non g�r�e 
#endif
Cependant, conna�tre toutes les macros pr�d�finies pour chaque OS, compilateur. est tr�s difficile.

La solution la plus rapide est d'aller visiter le site Pre-defined C/C++ Compiler Macros, qui maintient une liste � jour des macros pr�d�finies pour les choses suivantes :
  • Standard.
  • Compilateurs.
  • Syst�mes d'exploitation.
  • Biblioth�ques.
  • Architectures.

Une bonne habitude est �galement d'aller regarder les en-t�tes de biblioth�ques portables (par exemple boost). Ceux-ci sont truff�s de conditions sur les plateformes, et vous donneront de bonnes informations.

Mis � jour le 3 f�vrier 2007 Laurent Gomila

Une lvalue est, � l'origine, une expression qui peut se trouver du c�t� gauche lors d'une affectation, c'est-�-dire une expression � laquelle on peut affecter quelque chose. D�sormais, une lvalue d�signe toute expression qui fait r�f�rence � un objet, c'est-�-dire toute expression qui fait r�f�rence � une r�gion contig�e de m�moire. Cela peut donc �tre par exemple un objet constant, ce qui ne rentre pas forc�ment dans la d�finition utilisant l'affectation.

Par cons�quent, les identifiants (de variables) sont des lvalues. Il en va de m�me pour les r�f�rences.

Voici un code qui va peut-�tre aider � la compr�hension :

Code c++ : S�lectionner tout
1
2
3
4
5
6
int n = 5; // n est une lvalue 
Client& getClient() { /* ... */ } 
getClient() = UnAutreClient; // getClient() d�signe ici une lvalue car la r�f�rence renvoy�e correspond � la d�finition d'une lvalue 
  
std::string s = "C++"; // s est une lvalue 
// ...
Une rvalue est, � l'origine, une expression qui peut appara�tre du c�t� droit d'une affectation mais pas du c�t� gauche.
De fa�on peut-�tre plus claire, on d�finit une rvalue comme une expression qui n'est pas une lvalue.

Les temporaires par exemple sont des rvalues. Les rvalues peuvent �tre consid�r�es comme des � valeurs � d'expressions (constantes, r�sultat d'�valuations d'expressions�).

Il est utile de conna�tre ces notions et savoir les distinguer pour avoir une meilleure ma�trise de son code, savoir ce que l'on peut modifier, ce que l'on ne peut pas et ainsi donner le droit ou non de modifier des objets lorsque l'on cr�e des fonctions notamment.

Mis � jour le 15 octobre 2009 Alp

Les variables volatiles sont des variables qui peuvent �tre modifi�es par un processus hors de contr�le du compilateur. On doit acc�der � une copie de la variable si elle a pu �tre modifi�e.
Seules des fonctions membres volatiles peuvent �tre appel�es pour des objets volatils, et des fonctions membres volatiles ne peuvent appeler que des autres fonctions membres volatiles. La viralit� peut �tre d�tourn�e.
Le compilateur s'assure qu'aucune fonction membre n'ait d'optimisation quant aux r�f�rences m�moire. En l'absence du mot-clef volatile, il peut optimiser le code de la fonction membre.
Cependant, la pr�sence de ce mot-clef n'emp�chera pas le processeur d'optimiser pour la coh�rence des caches.
Utilisez ce mot-clef pour des variables que vous ne voulez pas voir optimis�es par le compilateur.
Il est faux de penser que ce mot-clef apporte la moindre s�curit� face au mutlithread. Il faut pour cela attendre le mot-clef atomic du C++0x.
Voici un petit exemple d'utilisation.

Code c++ : S�lectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Gadget 
{ 
public: 
    void attendre() 
    { 
        while (! _drapeau) 
        { 
            dormir(1000); // attend 1000 ms 
        } 
    } 
    void seLever() 
    { 
        _drapeau = true; 
    } 
    // ... 
private: 
    volatile bool _drapeau; 
};
Cette classe est pr�vue pour attendre qu'un autre thread vienne modifier une de ses variables membres, et v�rifier la situation toutes les secondes.
Si la variable n'avait pas �t� d�clar�e volatile, le compilateur aurait cru qu'il n'y a qu'un appel � une fonction externe qui ne peut modifier le drapeau. Il en aurait conclu qu'il peut mettre le drapeau en cache. Ceci fonctionne tr�s bien quand il n'y a qu'un thread. Avec le mot-clef, le compilateur comprend que la variable peut �tre modifi�e de l'ext�rieur, et ne la mettra pas en cache.

Mis � jour le 15 octobre 2009 dourouc05

On parle d'immuabilit� (ou non-mutabilit�) d'un �l�ment (au sens large) lorsque celui-ci ne change pas, tout au long de sa dur�e de vie. En C++, il faut distinguer plusieurs cas d'immuabilit� :

  • immuabilit� de membres ;
  • immuabilit� des param�tres ;
  • fonctions membres ne modifiant pas l'objet ;
  • types immuables.

L'immuabilit� en C++ se d�clare au moyen du mot cl� const.
Pour l'immuabilit� d'un membre :

Code c++ : S�lectionner tout
1
2
3
4
class C { 
    int const TAILLE_MAX; 
    // [...] 
};
Une fois affect�e (dans le constructeur), TAILLE_MAX ne pourra plus �tre modifi�e. const s'applique normalement � ce qui le pr�c�de (� sa gauche), et � d�faut � ce qui le suit (� sa droite). On prendra donc l'habitude d'�crire int const plut�t que const int, m�me si les deux sont �quivalents, et on comprendra alors plus facilement la diff�rence entre int const * et int * const.
Pour l'immuabilit� d'un param�tre :

Code c++ : S�lectionner tout
1
2
3
4
int longueur(std::string const & chaine) 
{ 
    // [...] 
}
Ici, on garantit � l'appelant qu'on ne modifie pas le param�tre qu'il nous donne (bien que celui-ci soit pass� par r�f�rence). L'appelant peut se baser sur cet engagement lorsqu'il valide son algorithme.
Fonctions membres ne modifiant pas l'objet :

Code c++ : S�lectionner tout
1
2
3
4
5
class chaine { 
public: 
    int longueur() const; 
    // [...] 
};
Ici, de la m�me mani�re, on garantit � l'appelant que le param�tre this (l'objet courant) n'est pas modifi� par cet appel. C'est � dire qu'aucun des membres de l'objet n'est modifi�, l'objet reste dans le m�me �tat. Un corolaire int�ressant de ceci est que (hors acc�s concurrents), deux appels successifs � une fonction membre const doivent donner le m�me r�sultat (c'est une garantie s�mantique - apparent�e � un contrat -, puisqu'en pratique, de nombreuses fa�ons existent de la d�tourner).
Si un type ne poss�de que des fonctions membres ne modifiant pas l'objet, alors, il n'existe aucun moyen de modifier cet objet et il est dit immuable (ou non-mutable). Cette notion est moins importante en C++ que dans d'autres langages, du fait que n'importe quel objet mutable devient immuable par l'usage du mot cl� const.

Il existe toutefois plusieurs restrictions :
  • Dans une fonction membre const, les membres pointeurs sont de type X* const, et non X const * const. Ceci fait qu'il est tout � fait l�gal d'�crire le code suivant :

    Code c++ : S�lectionner tout
    1
    2
    3
    4
    5
    class A { 
        int * m_val; 
    public: 
        int IncrementByOne() const { return  ++(*m_val); } 
    };
    Pour justifier ce comportement, prenez l'exemple d'un smart_pointer. Il est logique qu'un smart_ptr<int> const se comporte de la m�me mani�re qu'un int * const, tandis qu'un smart_ptr<const int> se comportera comme un int const *.
  • Les membres d�clar�s avec le mot cl� mutable ignorent les r�gles d'immuabilit� impos�es par const. Ceci permet des impl�mentations par compteur de r�f�rences sur des objets const, par exemple.
  • Il est possible � tout moment, au moyen de const_cast, de forcer la mutabilit� d'une variable immuable.

Il convient donc de se rappeler que const a avant tout valeur d'indication s�mantique, et l'utiliser � bon escient. const bien utilis� facilite la maintenance du code (on sait ce qui change), ainsi que l'utilisation du code par un tiers (limitation des effets de bord). En revanche, un const volontairement d�tourn� obfusque le code et rend complexe sa compr�hension.
En r�gle g�n�rale, on utilisera donc const chaque fois que c'est possible, et on utilisera mutable et const_cast uniquement lorsque c'est absolument n�cessaire et que �a n'induit pas de comportement contre-intuitif (fonction const qui aurait des effets de bord, par exemple.).

Mis � jour le 15 octobre 2009 white_tentacle

Il arrive que l'on veuille charger une biblioth�que dynamique (.dll, .so) explicitement depuis le code C++, que ce soit pour impl�menter un syst�me de plugins ou tout simplement car on ne dispose pas des fichiers de lien statique (.lib, .a). Cette manipulation est sp�cifique � chaque syst�me, mais on peut cependant remarquer que les principes et les fonctions mis en jeu sont pratiquement �quivalents, au nom pr�s.
En l'occurrence, cela se fait en trois �tapes :

  • Charger la biblioth�que dynamique
  • R�cup�rer les fonctions qu'elle exporte
  • D�charger la biblioth�que dynamique

Voici un code qui met en �uvre ce proc�d�, avec de simples macros pour prendre en charge plusieurs syst�mes (Windows et Linux) et ainsi obtenir un code plus ou moins portable :

Code c++ : S�lectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
// Version pour Windows 
#if defined(_WIN32) || defined(__WIN32__) 
  #include <windows.h> 
  #define DYNLIB_HANDLE         HMODULE 
  #define DYNLIB_LOAD( a )      LoadLibrary( a ) 
  #define DYNLIB_GETSYM( a, b ) GetProcAddress( a, b ) 
  #define DYNLIB_UNLOAD( a )    !FreeLibrary( a ) 
  #define DYNLIB_ERROR( )       "Unknown Error" 
  
// Version pour Linux 
#elif defined(linux) || defined(__linux) 
  #include <dlfcn.h> 
  #define DYNLIB_HANDLE         void* 
  #define DYNLIB_LOAD( a )      dlopen( a, RTLD_LAZY ) 
  #define DYNLIB_GETSYM( a, b ) dlsym( a, b ) 
  #define DYNLIB_UNLOAD( a )    dlclose( a ) 
  #define DYNLIB_ERROR( )       dlerror( ) 
#endif 
  
#include <iostream> 
  
int main() 
{ 
    // Chargement de la bibliothèque 
    DYNLIB_HANDLE Lib = DYNLIB_LOAD("library"); 
    if (!Lib) 
    { 
        std::cerr << DYNLIB_ERROR() << std::endl; 
        return EXIT_FAILURE; 
    } 
  
    // Importation de la fonction qui nous intéresse 
    typedef int (*FuncType)(float); 
    FuncType Func = static_cast<FuncType>(DYNLIB_GETSYM(Lib, "Function")); 
    if (!Func) 
    { 
        std::cerr << DYNLIB_ERROR() << std::endl; 
        return EXIT_FAILURE; 
    } 
  
    // Appel de la fonction importée 
    int x = Func(5.f); 
  
    // Déchargement de la bibliothèque 
    if (DYNLIB_UNLOAD(Lib)) 
    { 
        std::cerr << DYNLIB_ERROR() << std::endl; 
        return EXIT_FAILURE; 
    } 
  
    return EXIT_SUCCESS; 
}
La plupart des biblioth�ques graphiques encapsulent ces fonctions, comme par exemple wxWidgets (wxDynamicLibrary), Qt (QLibrary), SDL (SDL_LoadObject), etc.

Mis � jour le 15 octobre 2009 Laurent Gomila

Proposer une nouvelle r�ponse sur la FAQ

Ce n'est pas l'endroit pour poser des questions, allez plut�t sur le forum de la rubrique pour �a


R�ponse � la question

Liens sous la question
pr�c�dent sommaire suivant
 

Les sources pr�sent�es sur cette page sont libres de droits et vous pouvez les utiliser � votre convenance. Par contre, la page de pr�sentation constitue une �uvre intellectuelle prot�g�e par les droits d'auteur. Copyright � 2025 Developpez Developpez LLC. Tous droits r�serv�s Developpez LLC. Aucune reproduction, m�me partielle, ne peut �tre faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'� trois ans de prison et jusqu'� 300 000 � de dommages et int�r�ts.