Typo typo générant la plupart des messages d'erreur de la compilation C ++


51

Il semble que de simples modifications apportées à un fichier C ++, en particulier avec des modèles, peuvent générer des pages d'erreur. Ce concours a pour but de voir quel est le plus gros "bang of the buck", c’est-à-dire la sortie d’erreur la plus prolixe entraînant la moindre modification du code source (ajout de 1 caractère).

Etant donné que les autres langages sont plus sains, cela sera limité à C ++ et à la version 4.x de gcc.

Règles

  1. Le fichier source original doit être compilé avec gcc 4.9.2 pour code objet sans erreur.

  2. Un caractère ASCII est ajouté au code source pour créer une faute de frappe, ce qui augmente la taille du fichier d'un octet.

  3. Le compilateur est exécuté avec les options par défaut. Les options nécessaires telles que -cet -std=c++11sont autorisées, les options telles que -Wallne le sont pas.

  4. La métrique est

        number of bytes of generated error messages
        -----------------------------------------------------------------------
        (bytes of source code with typo) (length of filename passed to compiler)
    
  5. Les réponses seront validées avec http://ideone.com/ C ++ 4.9.2.

Exemple:

Le nom de fichier est a.cpp, ce qui fait 5 octets de long.

int foo();

Compilation de travail

 gcc -c a.cpp

Code source corrompu:

in t foo();

Échec de la compilation

$ gcc -c a.cpp
a.cpp:1:1: error: ‘in’ does not name a type
in t foo();
  ^
$ gcc -c a.cpp |& -c wc
64
$ wc -c a.cpp
12 a.cpp

Score: 64/12/5 = 1.0666

Meilleure tentative: insérer {entre parens defoo()

$ gcc -c a.cpp |& wc -c
497

Nouveau score: 497/12/5 = 8.283

Bonne chance!

MISE À JOUR

J'encourage les gens à ignorer la mise en œuvre récursive. Techniquement, cela gagne mais n’est pas dans l’esprit du concours.

MISE À JOUR 2

Comme beaucoup de personnes l’ont noté, le concours aurait probablement été plus intéressant si le pré-processeur C n’était pas autorisé. Je voudrais donc encourager les gens à publier des solutions qui n'utilisent pas du tout les commandes de pré-processeur. Cela n'implique aucune utilisation des fichiers d'en-tête, car ce #includen'est pas autorisé!

Pour ce qui est d’utiliser IDEONE pour valider, vous êtes autorisé à utiliser directement la sortie IDEONE (et le nom de source en tant que prog.cpp), ou vous pouvez exécuter la sortie IDEONE via une recherche et un remplacement globaux ( s/prog.cpp/a.cc/par exemple) et prétendre que vous avez pu: définir le nom du fichier directement.

MISE À JOUR 3

Comme les gens l'ont souligné, Ideone est un peu trop restrictif et requiert des liens, pas seulement la création de fichiers objets. Comme ce concours est purement amusant, soyez honnête et précisez ce que vous avez utilisé pour obtenir votre score. Vous pouvez soit utiliser ideone, soit utiliser la version la plus généreuse (toutes les valeurs par défaut) de gcc 4.9.2, comme vous le pouvez. Le concours a pour but de faire prendre conscience de l’atrocité des messages d’erreur C ++.


Les commentaires ne sont pas pour une discussion prolongée; cette conversation a été déplacée pour discuter . Autrement, pour discuter de ce qui devrait ou ne devrait pas compter comme un doublon, veuillez prendre la discussion au méta .
Martin Ender

Trois problèmes liés à l'utilisation d'ideone pour valider: forcer le nom du fichier source à "prog.cpp", tronquer la sortie d'erreur du compilateur à 64 ko et lier, en ajoutant des erreurs supplémentaires. Ce ne sera donc pas un bon outil de validation.
Jason C

J'utilise GCC 4.9.2 à partir du référentiel toolchain-test Ubuntu.
nneonneo

Quelles sont les options par défaut? Autant que je sache, vous pouvez configurer les options par défaut de gcc au moment de la compilation.
FUZxxl

2
Rappelle des souvenirs: à partir de 1975 environ, notre professeur de physique organisait chaque année un concours
intitulé

Réponses:


45

gcc 4.5.2, score: 8579.15 (ou 14367.49 pour le nom de fichier "aC", pourra éventuellement être mise à jour ultérieurement)

Le fichier original, 29 octets, compile proprement (a.cpp):

#if 0
#include"a.cpp"
#endif

Fichier modifié, 30 octets:

#iff 0
#include"a.cpp"
#endif

Les erreurs:

$ gcc -c a.cpp 2>&1 | wc -c
1286873

But:

1286873 / (30 * 5) = 8579,15

Tête et queue de la sortie d'erreur:

a.cpp:1:2: error: invalid preprocessing directive #iff
In file included from a.cpp:2:0:
a.cpp:1:2: error: invalid preprocessing directive #iff
In file included from a.cpp:2:0,
                 from a.cpp:2:
a.cpp:1:2: error: invalid preprocessing directive #iff
In file included from a.cpp:2:0,
                 from a.cpp:2,
                 from a.cpp:2:
a.cpp:1:2: error: invalid preprocessing directive #iff
In file included from a.cpp:2:0,
                 from a.cpp:2,
                 from a.cpp:2,
                 from a.cpp:2:
a.cpp:1:2: error: invalid preprocessing directive #iff
In file included from a.cpp:2:0,
                 from a.cpp:2,
                 from a.cpp:2,
                 from a.cpp:2,
                 from a.cpp:2:
a.cpp:1:2: error: invalid preprocessing directive #iff
In file included from a.cpp:2:0,
                 from a.cpp:2,
                 from a.cpp:2,
                 from a.cpp:2,
                 from a.cpp:2,
                 from a.cpp:2:

... And so on, backing out with second error after max include depth:

a.cpp:3:2: error: #endif without #if
In file included from a.cpp:2:0,
                 from a.cpp:2,
                 from a.cpp:2,
                 from a.cpp:2,
                 from a.cpp:2:
a.cpp:3:2: error: #endif without #if
In file included from a.cpp:2:0,
                 from a.cpp:2,
                 from a.cpp:2,
                 from a.cpp:2:
a.cpp:3:2: error: #endif without #if
In file included from a.cpp:2:0,
                 from a.cpp:2,
                 from a.cpp:2:
a.cpp:3:2: error: #endif without #if
In file included from a.cpp:2:0,
                 from a.cpp:2:
a.cpp:3:2: error: #endif without #if
In file included from a.cpp:2:0:
a.cpp:3:2: error: #endif without #if
a.cpp:3:2: error: #endif without #if

Remarque:
- Si vous .Cvous qualifiez comme extension valide, le score est de 1 206 869 / (28 * 3) = 14 367,49.
- Si le second #include suggéré par Dennis est ajouté, nom de fichier "a.cpp", le score est de 80 797 292 934 / (46 * 5) = 351 292 578,97


2
La question dit d'ajouter un caractère, pas de le remplacer.
Dennis

3
@ Dennis Oh mec. J'ai eu ça. Regardez cette deuxième édition. Votre commentaire était une bénédiction déguisée.
Jason C

1
@JasonC Je ne peux pas voter cela assez de fois.
isaacg

9
Je pense que vous pouvez réclamer un score infini si vous ajoutez une seconde #include"a.cpp".
Dennis

3
@Dennis Whoa, gentil! Je vais laisser la réponse telle quelle car je ne pensais pas en ajouter une seconde #includemoi-même. Pour ce qui est de l'infini ... si ça fonctionne toujours quand je me lève demain matin, c'est assez infini pour moi. Je vous tiendrai au courant, ha (même si, actuellement, il passe à 5,1 Mo / s wc. Si wcun compteur 32 bits est utilisé, il se peut que quelque chose de bizarre se produise en 13 minutes environ.)
Jason C

31

gcc 4,9,2, score: 222 898 664 663 393 783

Ceci est largement basé sur la réponse de @ JasonC , mais il a déclaré qu'il ne voulait pas se vanter de cette amélioration.

La sortie d'erreur du code ci-dessous a une longueur de 126 044 818 789 octets. Le score devrait être beaucoup plus élevé en théorie (et tendre vers l'infini à mesure que le nombre d'énoncés d'inclusion augmente), mais il diminue dans la pratique en ajoutant d'autres énoncés d'inclusion.

Fichier d'origine (37 octets)

/*#
#include"w.cpp"
#include"w.cpp"*/
$ gcc -c w.cpp
$

Fichier modifié (38 octets)

/
*#
#include"w.cpp"
#include"w.cpp"*/
$ gcc -c w.cpp
w.cpp:2:2: error: stray ‘#’ in program
 *#
  ^
In file included from w.cpp:3:0:
w.cpp:2:2: error: stray ‘#’ in program
 *#
  ^
In file included from w.cpp:3:0,
                 from w.cpp:3:
w.cpp:2:2: error: stray ‘#’ in program
 *#
  ^
In file included from w.cpp:3:0,
                 from w.cpp:3,
                 from w.cpp:3:
w.cpp:2:2: error: stray ‘#’ in program
 *#
  ^
In file included from w.cpp:3:0,
                 from w.cpp:3,
                 from w.cpp:3,
                 from w.cpp:3:
⋮
w.cpp:2:2: error: stray ‘#’ in program
 *#
  ^
w.cpp:3:0: error: #include nested too deeply
 #include"w.cpp"
 ^
w.cpp:4:0: warning: extra tokens at end of #include directive
 #include"w.cpp"*/
 ^
w.cpp:4:0: error: #include nested too deeply
w.cpp:2: confused by earlier errors, bailing out
The bug is not reproducible, so it is likely a hardware or OS problem.

6
Techniquement, cela ne produira pas une sortie infinie , bien qu'avec la technologie informatique actuelle (ou prévisible), vous ne vivrez pas assez longtemps pour la voir s'arrêter. Fondamentalement, GCC a une #includelimite d'imbrication de 200 niveaux, de sorte que votre récursif #includedevient efficacement un compteur binaire de 200 bits.
Ilmari Karonen

3
Ajoutez simplement des lignes d'inclusion pour obtenir un score infini. La taille de sortie augmente plus rapidement que le code.
jimmy23013

Cela aurait également pu être basé sur l' une des réponses d'une question précédente .
Peter Taylor

2
Il a fini ce matin, avec un nombre énorme qui a commencé avec un 8, et j'ai accidentellement fermé la fenêtre avant de copier le nombre , parce que je suis génial. Je le lance à nouveau.
Jason C

3
@JasonC Je l'ai aussi exécuté et j'ai obtenu une sortie de 77 877 399 160 octets. C'est beaucoup moins infini que prévu, donc je le relancerai avec un nom de fichier plus court.
Dennis

25

gcc, 4.9.2, note: 22.2

Fichier d'origine: 0 octet (a.cpp)

Compile propre:

$ gcc -c a.cpp |& wc -c
0

Fichier modifié:

(

Les erreurs:

$ gcc -c a.cpp |& wc -c
111

But

111/1/5 = 22,2


4
Avez-vous déjà forcé cela brutalement? Je veux dire, est-ce le score le plus élevé pour un fichier de début de 0 octet?
Thomas Weller

Non, je n'ai pas forcé cette force. Je viens d'essayer 3 ou 4 personnages différents. C'était juste une réponse pour intéresser les gens au concours :)
Mark Lakata

23

11 126,95 9,105,44 2,359,37 1 645,94 266,88 points

Plus d'abus de préprocesseur! Cette fois, nous faisons pleurer la bibliothèque standard.

Sans faute de frappe:

#define typedf
#include<fstream>

Avec une faute de frappe:

#define typedef
#include<fstream>

Les erreurs:

In file included from /usr/include/c++/4.9/iosfwd:39:0,
                 from /usr/include/c++/4.9/ios:38,
                 from /usr/include/c++/4.9/istream:38,
                 from /usr/include/c++/4.9/fstream:38,
                 from a.C:2:
/usr/include/c++/4.9/bits/stringfwd.h:62:33: error: aggregate ‘std::basic_string<char> std::string’ has incomplete type and cannot be defined
   typedef basic_string<char>    string;   
                                 ^
/usr/include/c++/4.9/bits/stringfwd.h:68:33: error: aggregate ‘std::basic_string<wchar_t> std::wstring’ has incomplete type and cannot be defined
   typedef basic_string<wchar_t> wstring;   
                                 ^
/usr/include/c++/4.9/bits/stringfwd.h:78:34: error: aggregate ‘std::basic_string<char16_t> std::u16string’ has incomplete type and cannot be defined
   typedef basic_string<char16_t> u16string; 
                                  ^
/usr/include/c++/4.9/bits/stringfwd.h:81:34: error: aggregate ‘std::basic_string<char32_t> std::u32string’ has incomplete type and cannot be defined
   typedef basic_string<char32_t> u32string; 
                                  ^
In file included from /usr/include/wchar.h:36:0,
                 from /usr/include/c++/4.9/cwchar:44,
                 from /usr/include/c++/4.9/bits/postypes.h:40,
                 from /usr/include/c++/4.9/iosfwd:40,
                 from /usr/include/c++/4.9/ios:38,
                 from /usr/include/c++/4.9/istream:38,
                 from /usr/include/c++/4.9/fstream:38,
                 from a.C:2:
/usr/include/stdio.h:48:25: error: aggregate ‘_IO_FILE FILE’ has incomplete type and cannot be defined
 typedef struct _IO_FILE FILE;
                         ^
/usr/include/stdio.h:64:25: error: aggregate ‘_IO_FILE __FILE’ has incomplete type and cannot be defined
 typedef struct _IO_FILE __FILE;
                         ^
In file included from /usr/include/c++/4.9/cwchar:44:0,
                 from /usr/include/c++/4.9/bits/postypes.h:40,
                 from /usr/include/c++/4.9/iosfwd:40,
                 from /usr/include/c++/4.9/ios:38,
                 from /usr/include/c++/4.9/istream:38,
                 from /usr/include/c++/4.9/fstream:38,
                 from a.C:2:
/usr/include/wchar.h:106:9: error: ‘__mbstate_t’ does not name a type
 typedef __mbstate_t mbstate_t;
         ^
/usr/include/wchar.h:151:38: error: ‘size_t’ is not a type
     const wchar_t *__restrict __src, size_t __n)
                                      ^
/usr/include/wchar.h:159:38: error: ‘size_t’ is not a type
     const wchar_t *__restrict __src, size_t __n)
                                      ^
/usr/include/wchar.h:166:63: error: ‘size_t’ is not a type
 extern int wcsncmp (const wchar_t *__s1, const wchar_t *__s2, size_t __n)
                                                               ^
/usr/include/wchar.h:176:4: error: ‘size_t’ is not a type
    size_t __n) __THROW;
    ^
In file included from /usr/include/wchar.h:180:0,
                 from /usr/include/c++/4.9/cwchar:44,
                 from /usr/include/c++/4.9/bits/postypes.h:40,
                 from /usr/include/c++/4.9/iosfwd:40,
                 from /usr/include/c++/4.9/ios:38,
                 from /usr/include/c++/4.9/istream:38,
                 from /usr/include/c++/4.9/fstream:38,
                 from a.C:2:
/usr/include/xlocale.h:42:9: error: ‘__locale_t’ does not name a type
 typedef __locale_t locale_t;
         ^
In file included from /usr/include/c++/4.9/cwchar:44:0,
                 from /usr/include/c++/4.9/bits/postypes.h:40,
                 from /usr/include/c++/4.9/iosfwd:40,
                 from /usr/include/c++/4.9/ios:38,
                 from /usr/include/c++/4.9/istream:38,
                 from /usr/include/c++/4.9/fstream:38,
                 from a.C:2:
/usr/include/wchar.h:183:5: error: ‘__locale_t’ is not a type
     __locale_t __loc) __THROW;
     ^
/usr/include/wchar.h:186:6: error: ‘size_t’ is not a type
      size_t __n, __locale_t __loc) __THROW;
      ^
/usr/include/wchar.h:186:18: error: ‘__locale_t’ is not a type
      size_t __n, __locale_t __loc) __THROW;
                  ^
/usr/include/wchar.h:196:8: error: ‘size_t’ does not name a type
 extern size_t wcsxfrm (wchar_t *__restrict __s1,
        ^
/usr/include/wchar.h:207:9: error: ‘__locale_t’ is not a type
         __locale_t __loc) __THROW;
         ^
/usr/include/wchar.h:212:8: error: ‘size_t’ does not name a type
 extern size_t wcsxfrm_l (wchar_t *__s1, const wchar_t *__s2,
        ^
/usr/include/wchar.h:252:8: error: ‘size_t’ does not name a type
 extern size_t wcscspn (const wchar_t *__wcs, const wchar_t *__reject)
        ^
/usr/include/wchar.h:256:8: error: ‘size_t’ does not name a type
 extern size_t wcsspn (const wchar_t *__wcs, const wchar_t *__accept)
        ^
/usr/include/wchar.h:287:8: error: ‘size_t’ does not name a type
 extern size_t wcslen (const wchar_t *__s) __THROW __attribute_pure__;
        ^
/usr/include/wchar.h:306:8: error: ‘size_t’ does not name a type
 extern size_t wcsnlen (const wchar_t *__s, size_t __maxlen)
        ^

[COUPER]

/usr/include/c++/4.9/bits/fstream.tcc:934:35: error: ‘cur’ is not a member of ‘std::ios_base’
    __testvalid = this->seekoff(0, ios_base::cur, _M_mode)
                                   ^
/usr/include/c++/4.9/bits/fstream.tcc:934:50: error: ‘_M_mode’ was not declared in this scope
    __testvalid = this->seekoff(0, ios_base::cur, _M_mode)
                                                  ^
/usr/include/c++/4.9/bits/fstream.tcc:941:25: error: ‘_M_state_last’ was not declared in this scope
    + _M_codecvt->length(_M_state_last, _M_ext_buf,
                         ^
/usr/include/c++/4.9/bits/fstream.tcc:944:15: error: ‘streamsize’ does not name a type
         const streamsize __remainder = _M_ext_end - _M_ext_next;
               ^
/usr/include/c++/4.9/bits/fstream.tcc:945:13: error: ‘__remainder’ was not declared in this scope
         if (__remainder)
             ^
/usr/include/c++/4.9/bits/fstream.tcc:949:35: error: ‘__remainder’ was not declared in this scope
         _M_ext_end = _M_ext_buf + __remainder;
                                   ^
/usr/include/c++/4.9/bits/fstream.tcc:951:25: error: ‘_M_state_cur’ was not declared in this scope
         _M_state_last = _M_state_cur = _M_state_beg;
                         ^
/usr/include/c++/4.9/bits/fstream.tcc:951:40: error: ‘_M_state_beg’ was not declared in this scope
         _M_state_last = _M_state_cur = _M_state_beg;
                                        ^
/usr/include/c++/4.9/bits/fstream.tcc:960:2: error: ‘_M_codecvt’ was not declared in this scope
  _M_codecvt = _M_codecvt_tmp;
  ^
/usr/include/c++/4.9/bits/fstream.tcc:960:15: error: ‘_M_codecvt_tmp’ was not declared in this scope
  _M_codecvt = _M_codecvt_tmp;
               ^
/usr/include/c++/4.9/bits/fstream.tcc:962:2: error: ‘_M_codecvt’ was not declared in this scope
  _M_codecvt = 0;
  ^

Sur ma machine Ubuntu, g++-4.9 -std=c++11 -c a.Cgénère 1 101 568 octets d’erreurs glorieuses, pour un score de 1101568/33/3 = 11 126,95.


7
Vous devriez écrire un programme pour analyser tous les en-têtes std et déterminer lequel #definevous donne le plus de points.
Jason C

1
Vous pouvez l'aggraver encore en le remplaçant typedefpar t;. Maintenant, non seulement vous cassez chaque utilisation de typedefmais vous obtenez une tonne d'erreurs "t ne nomme pas de type". Ou %;pour produire "id-non attendu attendu avant le jeton%".
MSalters

1
#define typename *et #define int class stdsemblait générer beaucoup plus d'erreurs.
jimmy23013

11

62.93 points

Juste de la magie noire méta C ++, compilée avec g++-4.8 -c -std=c++11 a.cc:

#include<memory>
template<int n>class B:std::unique_ptr<B<n-1>>{};template<>class B<0>{};B<-1>x;

Ungolfed:

#include <memory>

template<int n>
class B: std::unique_ptr<B<n-1>> {};

template<>
class B<0> {};

B<-1>x;

G ++ a une limite de récursivité de 900. Le passage B<1>à B<-1>une plage de 31 bits a donc un effet intéressant.

  • 96 octets de code (sans compter le final \n, ajoutent automatiquement certains éditeurs de texte, vimne le font pas).
  • Nom de fichier de 4 lettres, a.cc
  • 24165 octets de message d'erreur, et il est tronqué. Le message d'erreur complet contient 1235889 octets de contenu. Cela nécessiterait le -ftemplate-backtrace-limit=0changement. Cela signifierait également 3185 points pour moi!

std::unique_ptr est simplement la classe de modèle qui parvient à émettre le message d'erreur le plus long, détecté par essais et erreurs et par la connaissance de la STL et des chats, etc.


2
Mais ... comment puis-je me débarrasser de 6 espaces lorsque je n'en ai que 3 dans le code, @JasonC!
Stefano Sanfilippo

7

Score 7.865

À strictement parler, la réponse de 0 octet n'est PAS correcte, car ideone.com refusera de compiler le fichier sans erreur. La même chose est vraie avec l'exemple int foo();- il ne compilera pas sur ideone.com (je ne peux pas commenter à cause de la réputation manquante ...)

Donc, le plus petit programme possible à compiler sans aucun #includesest celui-ci:

int main(){}

Si vous modifiez cela en code suivant, il échouera avec 409 octets de code d'erreur (après avoir renommé prog.cpp en a.cc à partir de la sortie de ideone.com):

int main(){[}

409 / (13 * 4) = 7,865

Veuillez mettre à jour la question en conséquence, car les exemples donnés ne respectent pas les règles données ...


1
L'idéal est de faire toutes sortes de bêtises.
Jason C

Je suis d’accord, j’ai mis le cap sur la règle des idées après la publication de la question et les premières réponses données. Cat est en quelque sorte hors du sac maintenant.
Mark Lakata

1

C, nommé comme .cc

main(){constexprs a(){*(int*)0=f;}a(0)}

Code d'erreur:

.code.tio.cpp: In function ‘int main()’:
.code.tio.cpp:1:8: error: ‘constexprs’ was not declared in this scope
 main(){constexprs int a(f){*(int*)0=f;}a(0);}
        ^~~~~~~~~~
.code.tio.cpp:1:8: note: suggested alternative: ‘__cpp_constexpr’
 main(){constexprs int a(f){*(int*)0=f;}a(0);}
        ^~~~~~~~~~
        __cpp_constexpr
.code.tio.cpp:1:40: error: ‘a’ was not declared in this scope
 main(){constexprs int a(f){*(int*)0=f;}a(0);}

Bonjour encore! Quel est le programme original qui ne fait pas d'erreur? (Je suppose que c'est le cas main(){}, mais je ne suis pas sûr) En outre, n'est-ce pas simplement une amélioration de la réponse ci-dessus? Bien que vous puissiez certainement garder cette réponse, si elle était inspirée par celle de @ StefanM, vous devriez le mentionner. Enfin, maintenant que vous avez 50 représentants, vous pouvez commenter n'importe où.
NoOneIsHere

Je pense que cela est trop proche de la réponse de Stefan M.; Je signalerais ceci comme amélioration recommandée pour cette solution. Cela étant dit, les réponses en double sont autorisées. S'il vous plaît, mettez l'original ici cependant et mentionnez toutes les inspirations (bien qu'il soit possible que vous
veniez

1

Score 12.xx (erreur en effaçant un caractère)

S'il vous plaît pardonnez la violation de la règle 2 (IMHO ajouter OU supprimer un caractère serait dans l'esprit de la règle), mais cela m'est arrivé accidentellement (n'utilise donc pas de ruse "intentionnellement" abusive) lors de l'écriture de Real Code (TM) - le code de travail et le code source d’erreurs sont (ou ont l’air) simples et directs, j’ai donc pensé que c’était assez élégant pour les inclure ici. Code d'origine

#include <iostream>
using namespace std;
int main ()
{
cout<<"test"<<endl;
}

Code générant l'erreur (le dernier '<' a été supprimé, ce qui ressemble à une comparaison inférieure à, mais noooooooooooo ...)

#include <iostream>
using namespace std;
int main ()
{
cout<<"test"<endl;
}

Il ne s'agit que de 8241 octets de messages d'erreur du compilateur dans ideone.com g ++ 4.3.2.


1
Même si cela semble être dans l’esprit du défi (puisque le titre dit "une faute de frappe de caractère"), cela ne suit pas la règle 2 qui dit que vous pouvez uniquement ajouter un caractère, pas le supprimer ou le modifier.
Jo King
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.