Contenu | Rechercher | Menus

Annonce

DVD, clés USB et t-shirts Ubuntu-fr disponibles sur la boutique En Vente Libre

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 06/03/2009, à 19:21

toto59

pb compilation en c++ de hello world

Bonjour,
Je cherche à comprendre pourquoi la compilation du programme suivant :

#include <iostream.h>
int main()
{
    cout << "Hello world!\n";
    return 0;
}

me retourne après compilation :

laurent@laurent-desktop:~/Desktop/essai$ g++ main.cpp -o main
main.cpp:1:22: error: iostream.h: Aucun fichier ou dossier de ce type
main.cpp: In function ‘int main()’:
main.cpp:5: erreur: ‘cout’ was not declared in this scope

Pourriez-vous me donner des idées ou des pages qui pourraient m'indiquer comment réoudre ce pb ?

p.s : build-essential est bien installé sur la machine et un programme équivalent écrit en c (avec #include <stdio.h> et un printf) se compile parfaitement.

Hors ligne

#2 Le 06/03/2009, à 19:34

Vermouth

Re : pb compilation en c++ de hello world

Quand tu inclut une librairie(c'est le mot je croit) C++, il ne faut pas mettre de .h dans le nom.
donc:

#include <iostream>

De plus, pour y avoir accè normalement il faut ajouter:

using namespace std;

Après ton include.
Sinon il restera (le cout) dans le namespace iostream (sauf erreur, je suis pas trop calé en C++).

Ceci dit, je sais pas si tu suis un tuto mais ce genre d'infos ce trouve facilement (tuto, google)...

PS: un tour sur le site du zero, devellopez pour des tutos plus pousser

Dernière modification par Vermouth (Le 06/03/2009, à 19:36)


Android !
\_/°<

   coin coin...

Hors ligne

#3 Le 06/03/2009, à 19:47

toto59

Re : pb compilation en c++ de hello world

Merci beaucoup... ça marche parfaitement.

Je regarde sur le net pourquoi il faut enlever le .h et ce que signifie using namepace std et je post le pourquoi de la réponse

Hors ligne

#4 Le 06/03/2009, à 20:06

toto59

Re : pb compilation en c++ de hello world

Après recherche (très rapide), voila ce que j'ai trouvé sur developpez.com :

source http://cpp.developpez.com/faq/cpp/?page=console : Avant que le C++ ne soit normalisé, <iostream.h> était le seul fichier d'en-tête existant livré avec les compilateurs de l'époque. La normalisation ISO du C++ en 1998 a défini que <iostream> serait l'en-tête standard pour les entrées-sorties. L'absence de .h dans son nom indique qu'il s'agit désormais d'un en-tête standard, et donc que toutes ses définitions font partie de l'espace de nommage standard std. Inclure <iostream.h> est donc obsolète depuis ce temps là (techniquement parlant, <iostream.h> n'est pas obsolète car il n'a jamais fait partie du standard, mais son utilisation l'est).
Pour laisser le temps aux programmeurs de modifier leur code, les compilateurs ont fourni chacun de ces fichiers d'en-tête. <iostream.h> n'est donc encore présent que dans un but de compatibilité.
Mais maintenant certains compilateurs comme Visual C++ 7.1 (2003) ne fournissent plus que l'en-tête standard <iostream> et presque tous les autres émettent au moins un avertissement comme quoi utiliser <iostream.h> est obsolète. En le faisant, la portabilité et la compatibilité future de votre code sont menacées.
Voilà pourquoi il faut remplacer toute inclusion de <iostream.h>

En conclusion, il faut utiliser iostream car c'est le fichier qui respecte la normalisation et <iostream.h> est à proscrire car on ne veut plus de lui.

Concernant le using namespace stdio; voila ce que j'ai trouvé :

source http://cpp.developpez.com/faq/cpp/?page … _using_std : Toute la bibliothèque standard C++ est définie dans son propre espace de nom, le namespace std. Ainsi, il faut systématiquement utiliser le préfixe std:: devant tous les éléments qui en sont issus. Pour alléger l'écriture, on utilise l'expression using namespace std; ce qui permet de s'affranchir de l'obligation de préfixer par std::.

Cela veut dire que dans mon hello world les deux programmes (voir ci-dessous) fonctionnent et sont équivalent :

#include <iostream>
using namespace std;

int main()
{
 cout << "Hello world!\n";
 return 0;
}

et

#include <iostream>

int main()
{
 std::cout << "Hello world!\n";
 return 0;
}

Hors ligne

#5 Le 06/03/2009, à 21:37

Le Farfadet Spatial

Re : pb compilation en c++ de hello world

Salut à tous !

toto59 a écrit :

les deux programmes (voir ci-dessous) fonctionnent et sont équivalent

Pas tout à fait, car il y en a un des deux (le premier) qui présente une très mauvaise habitude de programmation, que je n'hésite pas à qualifier d'erreur : utiliser « using namespace » dans la portée générale.

   Les espaces de nommages (« namespace » dans la langue de Shakespeare) sont la pour palier à l'absence de module en C++, héritée du C. Pour faire simple, disons qu'ils sont là pour éviter les collisions de noms.

   Par exemple, admettons que tu codes un programme de géométrie. Admettons que tu as décidé d'accéder aux abscisses à l'aide de « abs. » Or, il se trouve que la bibliothèque standard possède la fonction « abs, » qui renvoie la valeur absolue. Comment faire la différence entre ces deux fonctions ?

   Avant l'existence des espaces de nommages, il fallait donner des noms qui ne soient pas redondant, par exemple en ajoutant le nom de la bibliothèque. On se retrouvait avec des noms à rallonge et malgré tout, les conflits de noms étaient difficiles à éviter.

   Les espaces de nommages apportent une solution élégante à ce problème. Cependant, en mettant « using namespace std; » dans la portée générale, tu supprimes de fait l'espace de nommage standard. Or, ces fonctions extrêmement usuelles font parties des plus susceptibles de provoquer des conflits de noms. Donc, cette instruction qui a l'air anodine et là soit-disant pour gagner du temps fait perdre un des intérêts du C++ et fait finalement perdre du temps, puisqu'il faut en revenir aux noms de fonctions à rallonge. À la rigueur, tu peux faire ceci :

#include <iostream>

int main (int argc, char **argv) {
  using namespace std;

   cout << "Salut tout le monde !" << endl;

  return 0;
}  // main

Mais même ça, je te le déconseille : le nom « std » a été choisi justement parce que sa brièveté rend l'utilisation de « using namespace std; » non-pertinente, afin que ces fonctions particulièrement utilisées puissent toujours être appelées avec leur nom d'espace de nommage. Donc, seul ton deuxième exemple est correcte.

   Pourquoi existe-t-elle, alors, cette instruction « using namespace ? » Principalement pour faire de la composition d'espace de nommage. Il y a également la possibilité de donner des alias aux noms d'espaces, mais ce sont des choses que tu découvriras plus tard. Pour l'instant, prends d'ors et déjà de bonnes habitudes en appelant toujours les fonctions de la bibliothèque standard avec leur nom d'espace de nommage : « std:: »

   À bientôt.

                                                                                                                                                                    Le Farfadet Spatial

Hors ligne

#6 Le 07/03/2009, à 12:09

Vermouth

Re : pb compilation en c++ de hello world

Oui tu as raison mais c'est au programmeur de faire attention !

Pour des petit programme pas de problème normalement, le jour ou tu (toto59) fera des gros programme, tu maitrisera serement ce détail !


Android !
\_/°<

   coin coin...

Hors ligne

#7 Le 07/03/2009, à 17:09

Link31

Re : pb compilation en c++ de hello world

Le Farfadet Spatial a écrit :

Pas tout à fait, car il y en a un des deux (le premier) qui présente une très mauvaise habitude de programmation, que je n'hésite pas à qualifier d'erreur : utiliser « using namespace » dans la portée générale.

+1

Et on trouve parfois des choses bien pires, comme l'utilisation d'un using namespace dans un header de bibliothèque... roll
Avec des fonctions comme log(), abs() ou le type FILE, ça peut faire très mal.

Dernière modification par Link31 (Le 07/03/2009, à 17:11)

Hors ligne

#8 Le 07/03/2009, à 17:53

Vermouth

Re : pb compilation en c++ de hello world

Et on trouve parfois des choses bien pires, comme l'utilisation d'un using namespace dans un header de bibliothèque... roll

Ce qui m'inquiète un peut, c'est qu'a la fac on nous fait utiliser ça lol !

Bon, généralement il ne donne que les bases au début (premier semestre qu'on nous aprent le C++), mais bon lol quois !


Android !
\_/°<

   coin coin...

Hors ligne

#9 Le 08/03/2009, à 04:00

nicolas66

Re : pb compilation en c++ de hello world

Tout à fait d'accord avec le post du Farfadet Spatial. Perso, j'autorise tout de même l'utilisation de l'espace de nom `std' seulement vers `cout' et `cerr', ça permet de gagner un peu de temps :

using std::cout;
using std::endl;

"The computer was born to solve problems that did not exist before." (B. Gates)

Hors ligne

#10 Le 09/03/2009, à 09:08

Le Farfadet Spatial

Re : pb compilation en c++ de hello world

Salut à tous !

Vermouth a écrit :

Oui tu as raison mais c'est au programmeur de faire attention !

En effet, c'est au programmeur de faire attention. En plus, c'est très simple : il ne faut jamais (absolument jamais) mettre de « using namespace » dans la portée générale.

Vermouth a écrit :

Pour des petit programme pas de problème normalement, le jour ou tu (toto59) fera des gros programme, tu maitrisera serement ce détail !

Non. Il ne faut pas faire ça, même dans les petits programmes : le cerveau est neutre, il apprend le bon comme le moins bon. Par contre, une fois une habitude prise, il est très long de revenir dessus. Donc, dès le début, dès les petits programmes, il ne faut jamais (absolument jamais) mettre de « using namespace » dans la portée générale.

Link31 a écrit :

Et on trouve parfois des choses bien pires, comme l'utilisation d'un using namespace dans un header de bibliothèque... roll
Avec des fonctions comme log(), abs() ou le type FILE, ça peut faire très mal.

Tu as bien raison.

Vermouth a écrit :

Ce qui m'inquiète un peut, c'est qu'a la fac on nous fait utiliser ça lol !

C'est tout le problème du C++ : il est généralement très mal enseigné, tant dans les livres, que dans les tutoriaux, les universités, les IUT, les BTS ou les grandes écoles.

nicolas66 a écrit :

Perso, j'autorise tout de même l'utilisation de l'espace de nom `std' seulement vers `cout' et `cerr'

À la rigueur, mais pas dans la portée générale. Cela dit, pour ma part, même ça je ne le fais jamais.

   À bientôt.

                                                                                                                                                                    Le Farfadet Spatial

Hors ligne

#11 Le 26/05/2009, à 19:02

Skippy le Grand Gourou

Re : pb compilation en c++ de hello world

Le Farfadet Spatial a écrit :
Vermouth a écrit :

Oui tu as raison mais c'est au programmeur de faire attention !

En effet, c'est au programmeur de faire attention. En plus, c'est très simple : il ne faut jamais (absolument jamais) mettre de « using namespace » dans la portée générale.

Je suis pas d'accord, c'est justement au programmeur de faire attention. Donc libre à lui d'utiliser un « using namespace » s'il connaît les risques qu'il prend et les assume.

Hors ligne

#12 Le 26/05/2009, à 20:10

Luc Hermitte

Re : pb compilation en c++ de hello world

Comme s'il travaillait seul et qu'il sera le seul mainteneur du projet ...

Hors ligne

#13 Le 26/05/2009, à 20:40

Vermouth

Re : pb compilation en c++ de hello world

rooo ! Pour un hello world ça doit se faire seul !
(blague lol)

Plus sérieusement, une fois qu'on a compris les namespaces, on en fait ce qu'on veut.
C'est sur tout mettre sur le std quand on import beaucoup de librairie c'est une mauvaise idée.
Mais perso je suis conscient de ce que je code, quand j'inclut je me demande toujours qu'est-ce que j'en fait.
Quand on fait ça a plusieurs c'est sur qu'il doit y avoir des convention sinon on s'en sort pas.

Là je pense que toto59 a compris le truc...
Sinon pour tout ce qui est librairie "standard" du C++, pas besoin de '.h' .

Tout cela dit je suis a peine initier au C++...


Android !
\_/°<

   coin coin...

Hors ligne

#14 Le 26/05/2009, à 21:41

Skippy le Grand Gourou

Re : pb compilation en c++ de hello world

Luc Hermitte a écrit :

Comme s'il travaillait seul et qu'il sera le seul mainteneur du projet ...

Pas mieux que Vermouth :
- si t'es seul, tu sais ce que tu fais ;
- si t'es en équipe, si les conventions sont pas définies c'est le bordel, point barre. Donc à l'équipe de décider, et ensuite à ses membres de savoir ce qu'ils font ;
- si tu reprends le projet d'un autre, t'es censé commencer par essayer de comprendre le code.

Hors ligne

#15 Le 26/05/2009, à 21:54

Le Farfadet Spatial

Re : pb compilation en c++ de hello world

Salut à tous !

   C'est dingue comme on peut tenter de justifier une mauvaise habitude, qui fait perdre du temps et provoque des bogues, alors que l'éviter n'est tout simplement pas contraignant...

Skippy le Grand Gourou a écrit :

Donc libre à lui d'utiliser un « using namespace » s'il connaît les risques qu'il prend et les assume.

Vermouth a écrit :

une fois qu'on a compris les namespaces, on en fait ce qu'on veut

Non : si on met un « using namespace » dans la portée générale, on supprime les espaces de nommages. On vient donc de supprimer un avantage de C++. Ce langage a suffisamment de problèmes pour qu'on en ajoute pas.

   C'est une catastrophe dès qu'on travaille en équipe, c'est-à-dire dès qu'on arrête de bricoler dans son coin. Mais même lorsque l'on est seul, c'est très dangereux : lorsque l'on revient sur son code trois mois plus tard, ce qui était évident ne l'est plus. De plus, il n'est pas rare que l'on reprenne des bouts de code que l'on a créé il y a longtemps, afin de ne pas réinventer la roue. Dès lors, si on s'est permis n'importe quoi, on est parti pour de longues nuits blanches.

   Contrairement à ce que vous pensez, mettre des « using namespace » dans la portée générale ne fait jamais gagner de temps, quelle que soit la situation dans laquelle on se trouve. Par contre, cela fait perdre très souvent beaucoup de temps et use la patience.

   Surtout, le cerveau est neutre : il apprend tout, le bon comme le mauvais. Par contre, il est difficile de se débarrasser d'une habitude. Donc, si on prend l'habitude de coder n'importe comment, on mettra beaucoup de temps à se corriger. Au contraire, si on prend dès le départ l'habitude de faire du code propre, ce sera parfaitement naturel.

   À bientôt.

                                                                                                                                 Le Farfadet Spatial

Dernière modification par Le Farfadet Spatial (Le 26/05/2009, à 22:17)

Hors ligne

#16 Le 26/05/2009, à 22:24

rniamo

Re : pb compilation en c++ de hello world

pour avoir testé (avant de comprendre l'utilité d'un namespace) sur un projet je plussoie wink


< Quelques un des mes programmes  | Cuisine Facile (pour les gourmands) | Fast MVC for PHP >
        \   ^__^
         \  (o o)\_______
            (___)\            )\

Hors ligne

#17 Le 26/05/2009, à 23:39

Skippy le Grand Gourou

Re : pb compilation en c++ de hello world

Le Farfadet Spatial a écrit :

C'est dingue comme on peut tenter de justifier une mauvaise habitude

tongue

Le Farfadet Spatial a écrit :

Non : si on met un « using namespace » dans la portée générale, on supprime les espaces de nommages. On vient donc de supprimer un avantage de C++. Ce langage a suffisamment de problèmes pour qu'on en ajoute pas.

Ben non, on supprime UN espace de nommage, celui de std. Ce qui n'empêche en rien d'en utiliser d'autres.

Le Farfadet Spatial a écrit :

C'est une catastrophe dès qu'on travaille en équipe, c'est-à-dire dès qu'on arrête de bricoler dans son coin. Mais même lorsque l'on est seul, c'est très dangereux : lorsque l'on revient sur son code trois mois plus tard, ce qui était évident ne l'est plus. De plus, il n'est pas rare que l'on reprenne des bouts de code que l'on a créé il y a longtemps, afin de ne pas réinventer la roue. Dès lors, si on s'est permis n'importe quoi, on est parti pour de longues nuits blanches.

Sauf si tu restes constant. Évidemment, si tu mets tous tes espaces de nom en global ça risque d'être le bordel… Mais si tu n'utilises qu'std en global, que tu le fais systématiquement, et que tu ne donnes pas de noms trop génériques à tes fonctions et objets, alors il n'y a pas de problème, à moins que quelqu'un t'ai convaincu entre temps de changer tes habitudes… wink

Le Farfadet Spatial a écrit :

Contrairement à ce que vous pensez, mettre des « using namespace » dans la portée générale ne fait jamais gagner de temps, quelle que soit la situation dans laquelle on se trouve. Par contre, cela fait perdre très souvent beaucoup de temps et use la patience.

Les seuls exemples où je me souviens avoir perdu du temps à cause de ça, c'était parce qu'il manquait le using namespace… wink

Le Farfadet Spatial a écrit :

Surtout, le cerveau est neutre : il apprend tout, le bon comme le mauvais. Par contre, il est difficile de se débarrasser d'une habitude. Donc, si on prend l'habitude de coder n'importe comment, on mettra beaucoup de temps à se corriger. Au contraire, si on prend dès le départ l'habitude de faire du code propre, ce sera parfaitement naturel.

C'est valable dans les deux sens, sans préjuger de ce qui est du « bon code » ou du « mauvais code » : si tu n'es pas habitué à utiliser std en global, tu auras beaucoup de mal à toucher à du code qui utilise using namespace std. Ce qui explique peut-être en partie ton animosité ? tongue

Hors ligne

#18 Le 27/05/2009, à 00:08

Le Farfadet Spatial

Re : pb compilation en c++ de hello world

Salut à tous !

Skippy le Grand Gourou a écrit :

Ce qui explique peut-être en partie ton animosité ?

Ça n'a rien d'une animosité, j'essaye juste de vous épargner les problèmes que j'ai traversés.

   J'ai commencé le C++ avant qu'il ne soit normalisé, ce qui remonte à un petit bout de temps. De fait, j'ai commis toutes les erreurs courantes faites en C++. Toutes les fois où, sur ce forum, je préviens d'une erreur de programmation en C++, c'est parce que j'ai déjà fait l'erreur de mon côté. Le raisonnement totalement spécieux que tu tiens, il y a de cela dix ans, c'est moi qui l'aurais tenu.

   Puis, j'ai subi les conséquences de cette habitude et j'ai bien vu qu'elle faisait perdre du temps et quelle posait des problèmes, problèmes que les espaces de nommages sont justement là pour résoudre.

   Mais bon, les vieux cons, on ne les écoute jamais. C'est dommage, car l'expérience des anciens permet de ne pas reproduire leurs erreurs...

Ben non, on supprime UN espace de nommage, celui de std. Ce qui n'empêche en rien d'en utiliser d'autres.

L'espace de nommage standard est sans doute l'espace de nommage le plus important, car c'est celui de la bibliothèque standard, c'est-à-dire le plus utilisé.

Évidemment, si tu mets tous tes espaces de nom en global ça risque d'être le bordel…

Non : dès que l'on ouvre ne serait-ce qu'un seul espace de nommage dans la portée globale c'est, comme tu le dis, « le bordel. »

tu ne donnes pas de noms trop génériques à tes fonctions et objets

Formidable : vive les noms à rallonges, qui rendent le code illisible... Les noms doivent être parlants, ce qui veut dire également qu'ils doivent être aussi génériques que l'est l'élément nommé et aussi long que nécessaire, mais pas plus.

   De toute façon, sans espace de nommage, les conflits de noms sont inéluctables.

Les seuls exemples où je me souviens avoir perdu du temps à cause de ça, c'était parce qu'il manquait le using namespace…

C'est parce que, globalement, tu n'utilises pas les espaces de noms. Une fois que tu en feras réellement usage, cela deviendra naturel et cela te fera gagner du temps.

si tu n'es pas habitué à utiliser std en global, tu auras beaucoup de mal à toucher à du code qui utilise using namespace std.

C'est totalement faux : par exemple, « std::abs() » fera toujours référence à la bonne fonction, même si quelqu'un a par erreur ajouté « using namespace std. »

   À bientôt.

                                                                                                                                 Le Farfadet Spatial

Hors ligne

#19 Le 27/05/2009, à 00:56

Skippy le Grand Gourou

Re : pb compilation en c++ de hello world

Tu as sans doute en grande partie raison, mais :

Le Farfadet Spatial a écrit :

Évidemment, si tu mets tous tes espaces de nom en global ça risque d'être le bordel…

Non : dès que l'on ouvre ne serait-ce qu'un seul espace de nommage dans la portée globale c'est, comme tu le dis, « le bordel. »

Je ne vois pas en quoi, à partir du moment où tu utilises les espaces de nom pour tout le reste… Personnellement quand je code je vois les éléments de l'espace std comme des éléments de base du C++, au même titre que les boucles while ou les tests if. Il ne me viendrait pas à l'esprit de nommer une fonction « abs() » ou « cout ». Et si je veux être propre, je préfixe mes propres fonctions par l'espace de nommage dans lesquelles elles sont définies, auquel cas je ne prends aucun risque…

Le Farfadet Spatial a écrit :

si tu n'es pas habitué à utiliser std en global, tu auras beaucoup de mal à toucher à du code qui utilise using namespace std.

C'est totalement faux : par exemple, « std::abs() » fera toujours référence à la bonne fonction, même si quelqu'un a par erreur ajouté « using namespace std. »

Certes, ce n'est pas ce que je voulais dire.

Hors ligne

#20 Le 27/05/2009, à 02:18

Luc Hermitte

Re : pb compilation en c++ de hello world

Les problèmes sont :
- les COTS dont certains sont tout sauf bien réalisés et qui vont utiliser des symboles pourtant définis dans std (pour des raisons historiques, ou d'incompétence (manque de recul ici), ou parce qu'il s'agit tout simplement de COTS C) -- tout va bien jusqu'au jour où l'on utilise ce COTS parce qu'il a l'air cool pour un problème ponctuel (ne serait-ce que faciliter l'écriture de tests unitaires), ou parce qu'il est nécessaire (comme une API propriétaire de dialogue avec un nouveau serveur qui a rejoint le projet)

- certains compilos qui ont des comportements étranges quand un #include est réalisé après using (Et ça c'est lourd. Très lourd!)

- le C++ est en pleine phase de mutation et de nouveaux symboles vont rejoindre std.

A chaque fois que le cas où des using de trop apparaissent, si le using est réalisé dans un .h inclus par quantité d'autres fichiers d'en-tête, on est parti pour une longue séance de compilation/correction incrémentale -- alors qu'il suffisait de configurer son éditeur dès le départ pour l'insérer sur un petit <alt-s> p.ex.

Maintenant, je ne code pas "rapidement" (pour ne pas dire à l'arrache) sur des projets jeunes avant de les abandonner, je suis plus dans la catégorie mainteneur/pompier. D'où ma plus grande sensibilité à la chose : je sais que le code évolue sans cesse (nouveaux COTS, montée de version des COTS, inclusions réorganisées, ...), et là le using ne me fait pas gagner du temps. Il m'en fait perdre en plantant les compilations.

Hors ligne

#21 Le 28/05/2009, à 17:25

cptpingu

Re : pb compilation en c++ de hello world

@Le Farfadet Spatial:
J'aime beaucoup ta vision des choses. Il est vrai qu'on voit beaucoup de conneries avec les espaces de nommages, et ça fait plaisir de voir que tous ne font pas n'importe quoi. C'est vraiment le genre de discours que je balançait à mes étudiants (lorsque j'enseignais).

Je te rassure, les écoles d'ingénieur font maintenant attention à cela. Pour ma part, à l'époque, mes profs "grepait" mon projet, et si la présence (non justifié) d'une seul "using namespace truc;" était détecté, j'avais 0 à l'intégralité de mon projet.
J'ai moi même appliqué cette méthode smile, très efficace contre ce genre de mauvaise habitude.

Hors ligne

#22 Le 05/01/2010, à 22:49

cptpingu

Re : pb compilation en c++ de hello world

Un article sur ce sujet:
http://0217021.free.fr/portfolio/axel.berardino/articles/bon-usage-using-namespace

Dernière modification par cptpingu (Le 05/01/2010, à 22:50)

Hors ligne