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

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

mon programme n'a pas besoin de toutes les instructions !


Sujet :

C++

  1. #1
    Membre du Club
    Inscrit en
    Juillet 2007
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 99
    Points : 46
    Points
    46
    Par défaut mon programme n'a pas besoin de toutes les instructions !
    Salut ,

    je suis novice en programmation C++, je viens de télécharger le compilateur sous msdos. j'ai touvé un cours d'initiation et je le suis à la lettre j'ai essayé le programme suivant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
     #include <stdio.h>
     main()
     {
        printf("hello, world\n");
        return 0;
     }
    J'ai remarqué que si on enlève #include <stdio.h> ou return 0; ça marche toujours

    Pouvez vous me dire pourquoi?

  2. #2
    Membre éclairé Avatar de Bayard
    Inscrit en
    Juin 2002
    Messages
    863
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 863
    Points : 718
    Points
    718
    Par défaut
    1) Je pense que cela n'est pas normal.

    Il faut préciser quel est le compilateur (aucun ne devrait dire cela).

    2) Ici c'est le forum C++. Pas le forum C.

    3) Pourquoi utiliser msdos en 2007 ?

  3. #3
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Points : 2 640
    Points
    2 640
    Par défaut
    Citation Envoyé par Bayard Voir le message
    3) Pourquoi utiliser msdos en 2007 ?
    Il a pas encore changé son PC

  4. #4
    Membre confirmé
    Homme Profil pro
    Consultant MOA
    Inscrit en
    Juillet 2004
    Messages
    289
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant MOA
    Secteur : Conseil

    Informations forums :
    Inscription : Juillet 2004
    Messages : 289
    Points : 635
    Points
    635
    Par défaut
    Pour le return 0, ça dépend du compilateur.
    Si tu ne spécifie aucun type de retour, le compilo peut l'interpréter comme un void, et par conséquent ne pas retourner d'erreur ...

  5. #5
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    J'ai remarqué que si on enlève #include <stdio.h> ou return 0; ça marche toujours

    Pouvez vous me dire pourquoi?
    Ton code tel quel ne devrait déjà pas marcher. Ce n'est ni du C++ ni du C89 standard.
    ça marche seulement parce que ton compilateur est dans un mode tolérant. Active -Wall -Wextra -pedantic -ansi et tu auras les messages d'erreur.

  6. #6
    En attente de confirmation mail
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    133
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 133
    Points : 169
    Points
    169
    Par défaut
    Le shell d'UNIX (ou Linux) teste la valeur de retour d'un programme, d'où le return 0. Pour MSDOS j'ai oublié, je pense que ça sert pas. Normalement on utilise exit(0), car exit() ferme les flux d'E/S et libère la mémoire.

  7. #7
    Membre actif Avatar de lastrecrue
    Développeur Java
    Inscrit en
    Février 2006
    Messages
    360
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Février 2006
    Messages : 360
    Points : 278
    Points
    278
    Par défaut
    que tu enlève le return 0, encore c'est possible avec certain compilateur, mais si tu enlève le <stdio.h> c'est quand même étonnant......

  8. #8
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    Peut-être avec des entetes précompilées ou qqc du style.

  9. #9
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut Re:
    En C++ il vaut mieux même toujours écrire
    En C, lorsqu'on ne précise pas le type de retour d'une fonction alors c'est implicitement int. On peut également ne pas spécifier d'arguments, par exemple :
    Dans ce cas, cela signifie : f est une fonction (qui retourne un int). Point. Et non f est une fonction qui ne nécessite aucun argument. Et enfin, j'allais l'oublier, on peut ne pas déclarer une fonction qui retourne un int. C'est pourquoi on peut enlever le #include <stdio.h>, car printf (déclarée dans stdio.h) est une fonction qui retourne un int.

    Tel n'est pas le cas en C++. Donc le code que tu as posté est du C, pas du C++.

    Quant au return 0, le 0 retourné est appelé le code d'erreur de l'application. 0 indique généralement une fin normale. Le code d'erreur est destiné au système. Par exemple, sous Windows la ligne de commande :
    Execute cmd1 puis si et seulement si cmd1 s'est exécuté correctement, exécute cmd2. On dit qu'une commande s'est exécuté correctement si elle renvoie le code d'erreur 0 ou aucun code d'erreur.

  10. #10
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    En C++, il est obligatoire de déclarer le type de retour d'une fonction, donc main doit être déclaré :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int main() {}
    ou
    int main(int argc, char** argv) {} // ou autre variante pour les arguments
    Une fonction avec 0 arguments peut s'écrire soit avec une liste d'argument vide (comme je l'ai fait ci-dessus, soit avec void. En C++, la première écriture a tendance à être la plus courante.

    Pour ce qui est du stdio, il est nécessaire pour utiliser printf. Si tu ne l'inclues pas, le compilateur est sensé faire une erreur. Il est possible que les personnes ayant écrit le compilateur soient plus permissives que ce que demande le standard.

    Quoi qu'il en soit, en C++, on n'utilise généralement pas printf, il y a de bien meilleures alternatives. Si tu veux faire du C++, et non de C, il y a donc des chances que tu n'aies pas choisi le bon livre.

    Enfin ,pour le cas du return, main est une fonction qui retourne un int. Obligatoirement. Par contre il a été défini comme un cas particulier que pour cette fonction, et cette fonction uniquement, il est possible de ne pas spécifier la valeur de retour dans le code, auquel cas, le compilateur ajoutera tout seul un return EXIT_SUCCESS à la fin. Ce n'est pas une largesse du compilateur, mais un point défini dans la norme, et tout compilateur est sensé y adhérer.

  11. #11
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Le seul que je n'ai pas envie de corriger, c'est Loïc. Ça vous gènerait
    beaucoup de ne pas répondre sans être raisonnablement sûr de vous? Déjà
    que quand on est sûr on se plante parfois...

    Citation Envoyé par Minouchka Voir le message
    Salut ,

    je suis novice en programmation C++, je viens de télécharger le compilateur
    sous msdos. j'ai touvé un cours d'initiation et je le suis à la lettre j'ai
    essayé le programme suivant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #include <stdio.h>
    main()
    {
       printf("hello, world\n");
       return 0;
    }
    J'ai remarqué que si on enlève #include <stdio.h> ou return 0; ça marche
    toujours

    Pouvez vous me dire pourquoi?
    En C++, le programme tel quel ne doit pas compiler: le type de retour (int)
    est obligatoire.

    En C90, le programme tel quel n'a pas de problème. En C99, le type de
    retour est aussi obligatoire, comme en C++.

    Enlever le return 0, cause formellement un comportement indéfini (n'importe
    quoi peut arriver). En pratique cela ne pause pas de problèmes tant qu'on
    ne teste pas le résultat par après. En C++, c'est même autorisé, avec le
    même effet que return 0.

    Enlever l'include <stdio.h> est plus problématique. Oui, en C on peut
    utiliser une fonction qui n'est pas déclarée. Mais il faut le faire
    correctement et pour une fonction à nombre variable d'arguments comme
    printf, c'est pas possible. On a donc à nouveau un comportement indéfini,
    qui en pratique peut poser des problèmes et ne pas faire ce que tu veux.

    Citation Envoyé par Captain_JS Voir le message
    Pour le return 0, ça dépend du compilateur. Si
    tu ne spécifie aucun type de retour, le compilo peut l'interpréter comme un
    void, et par conséquent ne pas retourner d'erreur ...
    Non. En C++ et en C99, l'absence du type de retour est interdit. En C90,
    c'est autorisé mais c'est alors implicitement un int.

    Citation Envoyé par loufoque Voir le message
    Ton code tel quel ne devrait déjà pas marcher. Ce
    n'est ni du C++ ni du C89 standard.
    Et pourquoi ce n'est pas du C90 standard?

    Citation Envoyé par Zartan Voir le message
    Le shell d'UNIX (ou Linux) teste la valeur de retour
    d'un programme, d'où le return 0. Pour MSDOS j'ai oublié, je pense que ça
    sert pas.
    Si, on peut tester le résultat dans un batch. De mémoire EXITLEVEL ou
    quelque chose du genre.

    Normalement on utilise exit(0), car exit() ferme les flux d'E/S
    et libère la mémoire.
    La valeur de retour de main est passée à exit. Il n'y a absolument aucune
    différence.

    Citation Envoyé par Melem Voir le message
    En C++ il vaut mieux même toujours écrire
    En C++ il n'y a aucune raison de mettre void dans la liste de paramètre
    (même si c'est autorisé).

    En C, lorsqu'on ne précise pas le type de retour d'une fonction alors c'est
    implicitement int. On peut également ne pas spécifier d'arguments, par
    exemple : Dans ce cas, cela signifie : f est une
    fonction (qui retourne un int). Point. Et non f est une fonction qui ne
    nécessite aucun argument.[/quote]

    Dans une déclaration. Mais dans une définition c'est bien f ne prend aucun
    argument. Avec l'effet bizarre que
    défini f comme sans arguements mais la déclare sans rien préciser sur ses
    arguments...

    Et enfin, j'allais l'oublier, on peut ne pas déclarer une fonction
    qui retourne un int. C'est pourquoi on peut enlever le #include <stdio.h>,
    car printf (déclarée dans stdio.h) est une fonction qui retourne un
    int.
    On ne peut pas. printf est une fonction variadique et on ne peut pas les
    utiliser sans déclaration le précisant.

    0 indique généralement une fin normale.
    0 indique toujours une fin normale en C et en C++. Si ce n'est pas le cas
    pour l'OS (par exemple VMS), le runtime doit effectuer une transformation.

  12. #12
    Membre éprouvé Avatar de fenkys
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    376
    Détails du profil
    Informations personnelles :
    Âge : 57
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Octobre 2007
    Messages : 376
    Points : 1 054
    Points
    1 054
    Par défaut
    Je ne vois pas en quoi le fait que printf soit une fonction variadique gène en C90. Il me semblait qu'en l'absence de prototype, le compilateur reconstituait un prototype à partir des arguments de fonction et avec int pour type de retour (ici on aurait int printf (char *)) et qu'à l'édition de lien seul le nom de la fonction comptait, les arguments n'avaient aucun rôle. En C, seule le nom de la fonction compte pour sa signature, pas ses arguments. Donc printf devrait être trouvé même sans stdio et l'édition de lien devrait se faire.

    C'est cette absence de rôle des arguments de fonctions qui est à l'origine du mangling en C++ (puisque dans ce langage la signature d'une fonction dépend de son nom mais aussi de ses arguments) afin que l'éditeur de lien puisse différencier les fonctions de même nom mais ayant des arguments différents.

  13. #13
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par fenkys Voir le message
    Je ne vois pas en quoi le fait que printf soit une fonction variadique gène en C90.
    Parce que le 6ième paragraphe de la section 6.3.2.3 le dit.

    L'objectif est de ne pas imposer à tous les appels de fonctions le coût supplémentaire causé par une convention d'appel permettant un nombre variable d'arguments. Deux exemples de ce coût supplémentaire que peut introduire une telle convention:
    - un nombre variable d'argument ne permet pas sur un X86 d'utiliser comme convention d'appel "l'appelé enlève les arguments de la pile", vraissemblablement en utilisant l'argument de RET
    - il est intéressant de passer des arguments dans les registres. Etablir une convention d'appel permettant de le faire dans le cas des arguments passés pour ... n'est pas simple et coûterait vraissemblablement plus que ça ne rapporterait.

    Il me semblait qu'en l'absence de prototype, le compilateur reconstituait un prototype à partir des arguments de fonction et avec int pour type de retour (ici on aurait int printf (char *)) et qu'à l'édition de lien seul le nom de la fonction comptait, les arguments n'avaient aucun rôle. En C, seule le nom de la fonction compte pour sa signature, pas ses arguments. Donc printf devrait être trouvé même sans stdio et l'édition de lien devrait se faire.
    Le problème n'est pas à l'édition de liens mais à l'exécution.

    En l'absence de déclaration, une déclaration implicite comme int f() est faite (ce qui est une déclaration sans prototype).

    Quand un appel est fait pour une fonction avec une déclaration sans prototype (qu'elle soit implicite ou non, dans ce dernier cas elle peut retourner autre chose qu'un int), les arguments sont promus (les entiers de type "plus petit" que int en int/unsigned, les float en double -- pour un appel ciblant une fonction dont on a un prototype, les arguments sont convertis dans le type correspondant, ce qui peut ou pas correspondre effectivement à la promotion). Et si quelque chose ne va pas -- nombre d'arguments, paramètres avec des types incompatibles avec ceux des arguments après promotion, fonction avec nombre d'arguments variables -- le comportement est indéfini.

  14. #14
    Membre éprouvé Avatar de fenkys
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    376
    Détails du profil
    Informations personnelles :
    Âge : 57
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Octobre 2007
    Messages : 376
    Points : 1 054
    Points
    1 054
    Par défaut
    Le problème a l'execution existe depuis l'origine des temps du C il me semble.

    La phase de construction du programme fonctionne, mais en l'absence de possibilité de vérification par le prototype l'executable peut ne pas être correct. Ca fait d'ailleurs partie des piège dans lesquels tombe allégrement un débutant en C.

    En bref, nous sommes d'accord.

  15. #15
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par fenkys Voir le message
    Le problème a l'execution existe depuis l'origine des temps du C il me semble.

    La phase de construction du programme fonctionne, mais en l'absence de possibilité de vérification par le prototype l'executable peut ne pas être correct. Ca fait d'ailleurs partie des piège dans lesquels tombe allégrement un débutant en C.

    En bref, nous sommes d'accord.
    Je ne suis pas sûr. Ce n'est pas un problème de vérification que l'appel utilise bien des arguments du bon type -- dans l'exemple qui a généré cette discussion c'est le cas -- c'est que le code machine à générer pour un appel à une fonction variadique peut être différent de celui à générer pour un appel avec les mêmes arguments à une fonction normale.

  16. #16
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    Dans une déclaration. Mais dans une définition c'est bien f ne prend aucun argument.
    est une déclaration. Mais je reconnais que ca n'a pas grand chose à voir avec la fonction main. C'était juste pour info. Et merci pour la correction.

    On ne peut pas. printf est une fonction variadique et on ne peut pas les
    utiliser sans déclaration le précisant.
    Pourtant ça fait des années que je compile hello world sans erreur sans déclarer printf, et ce avec n'importe quel compilateur dont gcc et cl.exe . Je ne dis pas que c'est une bonne pratique.

  17. #17
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Melem Voir le message
    est une déclaration. Mais je reconnais que ca n'a pas grand chose à voir avec la fonction main. C'était juste pour info. Et merci pour la correction.


    Pourtant ça fait des années que je compile hello world sans erreur sans déclarer printf, et ce avec n'importe quel compilateur dont gcc et cl.exe . Je ne dis pas que c'est une bonne pratique.
    C'est la joie du comportement indéfini. C'est pas impossible de tomber sur des implémentations ayant l'air de faire ce que tu veux. (Pour celui-là, je crains plus la variation des processeurs que des compilateurs. Il faudrait essayer sur un processeur où le passage de paramètres se fait par registre autant que possible.)

Discussions similaires

  1. Mon programme ne trouve pas le package jt400
    Par Greg.shogun dans le forum JDBC
    Réponses: 2
    Dernier message: 11/05/2007, 11h21
  2. Réponses: 3
    Dernier message: 16/04/2007, 18h01
  3. Mon programme ne marche pas aprés le if:?
    Par mitherkiller dans le forum C
    Réponses: 28
    Dernier message: 28/03/2007, 20h47
  4. Mon programme ne fonctionne pas
    Par phil23 dans le forum C
    Réponses: 4
    Dernier message: 22/03/2007, 17h31
  5. Sos mon programme ne marche pas
    Par monalisa_dulouvre dans le forum C
    Réponses: 49
    Dernier message: 26/12/2006, 19h35

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo