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 :

Erreur incomprise émise par sqrt


Sujet :

C

  1. #1
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2013
    Messages
    120
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

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

    Informations forums :
    Inscription : Décembre 2013
    Messages : 120
    Points : 109
    Points
    109
    Par défaut Erreur incomprise émise par sqrt
    Je ne comprends pas cette erreur renvoyée par le compiltaeur.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     gcc Calcul.c -o calcul
    /tmp/ccxXBe9y.o*: Dans la fonction «*racine*»*:
    Calcul.c:(.text+0x94)*: référence indéfinie vers «*sqrtf*»
    collect2: error: ld returned 1 exit status
    Voici le proramme en question:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    #include <stdlib.h>
    #include <stdio.h>
    #include <math.h>
     
    #define ERROR 0
     
    float racine( float a ,float b);
     
    int main(int argc, char **argv){
     
     float a, b;
     
        a= 10;
        b= 10;
     
     printf( " %f\n ",racine(a,b));
     
       return 0;
     
    }
     
    float racine( float a ,float b){
     
     
    	if(a>=0 && b>=0){
     
     
     
         return sqrtf(a*b);
     
    	}
     
    	else{
    		return error;
    	}
     
    }
    Merci de votre

  2. #2
    Membre chevronné Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Points : 2 160
    Points
    2 160
    Par défaut
    Bonjour

    Réponse courte :
    Essaye de compiler avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gcc Calcul.c -o calcul -lm

  3. #3
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 291
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 291
    Points : 4 941
    Points
    4 941
    Billets dans le blog
    5
    Par défaut
    Pour pouvoir utiliser la bibliothèque math.h il faut l'indiquer au compilateur on y ajoutant -lm.

  4. #4
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2013
    Messages
    120
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

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

    Informations forums :
    Inscription : Décembre 2013
    Messages : 120
    Points : 109
    Points
    109
    Par défaut
    Merci
    Mais cela me soulève une autre question:
    faudra-t-il ajouter encore des options à chaque fois qu'on ajoute d'autres bibliothèques autres que le stdlib.h, stdio.h?

  5. #5
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    non, seul les maths sont dans une bibliothèque séparée.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  6. #6
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2013
    Messages
    120
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

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

    Informations forums :
    Inscription : Décembre 2013
    Messages : 120
    Points : 109
    Points
    109
    Par défaut
    Mais ce code par exemple ne requiert pas l'option -lm pour compiler.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <stdlib.h>
    #include <stdio.h>
    #include <math.h>
     
     
    int main(int argc, char **argv){
     
    	printf("%f", sqrt(4));
     
      return EXIT_SUCCESS;
    }
    Une explication ?

  7. #7
    Membre émérite
    Homme Profil pro
    sans emploi
    Inscrit en
    Janvier 2014
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : sans emploi
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2014
    Messages : 539
    Points : 2 601
    Points
    2 601
    Par défaut
    Citation Envoyé par ternel Voir le message
    non, seul les maths sont dans une bibliothèque séparée.
    Bonjour,

    la libc est une bibliothèque séparée. Mais lorsque tu compiles en mode hosted (= tu as un OS en gros) elle est automatiquement utilisée et c'est pourquoi il y a des options pour ne pas l'utiliser par défaut.
    Le cas de la libm est un peu particulièr, les fonctions math font partie de la bibliothèque standard du C mais certaines implémentations comme la gnu libc les mettent dans une bibliothèque à part pour d'obscures raisons historiques et posixiennes. D'autres implémentations comme musl mettent tout dans la bibliothèque libc sans trop se préoccuper de découpages antiques.
    La libc contient souvent aussi (sous *nix ou mac) les fonctions POSIX, mais certaines seront placées dans librt ou libpthread, et à nouveau il va falloir lier avec les bonnes bibliothèques dans ce cas. Les man pages t'indiquent en général ce qu'il faut faire.

  8. #8
    Membre émérite
    Homme Profil pro
    sans emploi
    Inscrit en
    Janvier 2014
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : sans emploi
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2014
    Messages : 539
    Points : 2 601
    Points
    2 601
    Par défaut
    Citation Envoyé par free_01_binairy Voir le message
    Mais ce code par exemple ne requiert pas l'option -lm pour compiler.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <stdlib.h>
    #include <stdio.h>
    #include <math.h>
     
     
    int main(int argc, char **argv){
     
    	printf("%f", sqrt(4));
     
      return EXIT_SUCCESS;
    }
    Une explication ?
    Les compilateurs comme gcc ont des builtins = des fonctions qui bypassent les fonctions standards pour plusieurs raisons. De plus sqrt est une fonction pure = une fonction dont le résultat ne dépend que de ses paramètres et d'aucun autre état externe à la fonction → le compilateur va optimiser cela en utilisant sa fonction sqrt, calculer sqrt(4) et utiliser le résultat directement sans aucun appel à la fonction au runtime. Pas d'appel de la fonction au run time = pas besoin de son code = pas besoin de lier le programme avec la libm.

    Remarques : c'est sqrtf pour les float, sqrt c'est pour les doubles. Ici ça n'a pas trop d'importance mais bon. Ou alors il faut utiliser tgmath.h (type generic math header).

    Essaye avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #include <stdlib.h>
    #include <stdio.h>
     
    int main(int argc, char **argv){
     
            printf("%f", sqrt(4));
     
      return EXIT_SUCCESS;
    }
     
    float sqrt(float n)
    {
      return n+1;
    }
    pour avoir des surprises

  9. #9
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2013
    Messages
    120
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

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

    Informations forums :
    Inscription : Décembre 2013
    Messages : 120
    Points : 109
    Points
    109
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include <stdlib.h>
    #include <stdio.h>
     
    int main(int argc, char **argv){
     
            printf("%f", sqrt(4));
     
      return EXIT_SUCCESS;
    }
     
    float sqrt(float n)
    {
      return
    Comme vous n'avez mis de prototype, les warnings deviennent un peu trop.
    Ou c'est fait expres?
    Sans prototype j'ai ces avertissements ci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    racine.c: In function ‘main’:
    racine.c:20:22: warning: implicit declaration of function ‘sqrt’ [-Wimplicit-function-declaration]
             printf("%f", sqrt(4));
                          ^
    racine.c:20:22: warning: incompatible implicit declaration of built-in function ‘sqrt’
    racine.c:20:22: note: include ‘<math.h>’ or provide a declaration of ‘sqrt’
    racine.c: At top level:
    racine.c:25:7: warning: conflicting types for built-in function ‘sqrt’
     float sqrt(float n)
    Et avec un prototype defini:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    racine.c:16:7: warning: conflicting types for built-in function ‘sqrt’
     float sqrt(float n);
    Ce que je retiens, c'est qu'il y a un conflit de nom de fonction. étant donné que la fonction sqrt a déjà été definie dans la bibliothèque standard de C, Sa redefinition ici pose un conflit de nom.
    Quand j'essaie d'inclure la bibliothèque math.h, l'erreur devient plus explicite avec une plainte du compilateur m'avertissant que sqrt a éte definie dans .../mathcalls.h
    Comment eviter ces conflits de noms?
    Je sais qu'en PHP les namespaces peuvent bien gérer ça; ici je n'en sais rien.

  10. #10
    Membre émérite
    Homme Profil pro
    sans emploi
    Inscrit en
    Janvier 2014
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : sans emploi
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2014
    Messages : 539
    Points : 2 601
    Points
    2 601
    Par défaut
    Les warning t'indiquent dans l'ordre :
    • tu utilises une fonction dont le prototype n'a pas été rencontré ; par défaut le compilateur va décider que son prototype est int sqrt() = déclaration implicite
    • le compilo (qui est de plus en plus intelligent) remarque que c'est une fonction standard et t'indique que ton problème serait sans doute résolu en incluant le header indiqué si c'est ça que tu voulais faire.
    • le compilo t'indique ensuite qu'il va utiliser le built-in sqrt mais que tu ne lui as pas fourni le bon prototype → normal la déclaration implicite en int sqrt() est différente de double sqrt(double).


    mais le plus important (car ce programme compile) est de remarquer que bien que le code de la fonction sqrt fournit ne fait que renvoyer 1 + la valeur du paramètre, le résultat affiché est bien celui attendu par sqrt soit 2 et non 5 …

  11. #11
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par free_01_binairy Voir le message
    faudra-t-il ajouter encore des options à chaque fois qu'on ajoute d'autres bibliothèques autres que le stdlib.h, stdio.h?
    Bonjour

    Les ".h" ne sont pas des bibliothèques mais des headers. Bien qu'un header aille bien souvent de concert avec une bibliothèque, ce n'est pas la même chose.

    Pour simplifier: une bibliothèque c'est un truc qui te donne accès à des outils, et un ".h" c'est un truc qui contient la déclaration des outils en question. C'est dû au fait qu'une compilation se passe en 2 étapes: analyse sémantique du source (syntaxe, types etc) ce qui crée un équivalent binaire (on parle de "modules objet") et ensuite liaison entre les différents modules objets et éventuellement les outils des bibliothèques. Or, lors de la première phase, il est impératif que le compilo connaisse au-moins le type des outils en question => d'où le ".h".

    Citation Envoyé par free_01_binairy Voir le message
    Ce que je retiens, c'est qu'il y a un conflit de nom de fonction. étant donné que la fonction sqrt a déjà été definie dans la bibliothèque standard de C, Sa redefinition ici pose un conflit de nom.
    Quand j'essaie d'inclure la bibliothèque math.h, l'erreur devient plus explicite avec une plainte du compilateur m'avertissant que sqrt a éte definie dans .../mathcalls.h
    Comment eviter ces conflits de noms?
    Je sais qu'en PHP les namespaces peuvent bien gérer ça; ici je n'en sais rien.
    Bonjour

    Les namespace existent en php, C++, Python et probablement bien d'autres langages évolués mais pas en C. Donc tu ne peux pas résoudre les conflits et dans le cas de noms identiques, c'est le dernier qui gagne.

    Si par exemple tu crées une fonction "toto" dans une libA qui écrit "bonjour" et une autre dans une libB qui écrit "bye", ben si tu compiles avec "libA libB" tu auras "bye" alors que si tu compiles avec "libB libA" tu auras "bonjour".

    Mais généralement les conflits de noms sont plutôt assez rares...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  12. #12
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2013
    Messages
    120
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

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

    Informations forums :
    Inscription : Décembre 2013
    Messages : 120
    Points : 109
    Points
    109
    Par défaut
    Merci pour les details.
    Citation Envoyé par picodev
    mais le plus important (car ce programme compile) est de remarquer que bien que le code de la fonction sqrt fournit ne fait que renvoyer 1 + la valeur du paramètre, le résultat affiché est bien celui attendu par sqrt soit 2 et non 5 …
    Mais quand je fournis un prototype, le retour de a fonction est 1+ valeur passée en paramètre (5). Et non 2.
    Je veux pas faire durer le débat mais c'est juste une remarque.

  13. #13
    Membre émérite
    Homme Profil pro
    sans emploi
    Inscrit en
    Janvier 2014
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : sans emploi
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2014
    Messages : 539
    Points : 2 601
    Points
    2 601
    Par défaut
    Évidemment, tu peux te douter que j'ai construit l'exemple pour utiliser la fonction built-in malgré une définition … c'est fait exprès : c'est une chose qu''on ne doit jamais faire dans la vraie vie réelle …

  14. #14
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2013
    Messages
    120
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

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

    Informations forums :
    Inscription : Décembre 2013
    Messages : 120
    Points : 109
    Points
    109
    Par défaut
    Merci

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 25/08/2011, 11h59
  2. Erreur 3251 : mise à jour non prise en charge
    Par gletare dans le forum Access
    Réponses: 2
    Dernier message: 10/02/2006, 10h17
  3. erreur avec pow et sqrt
    Par salseropom dans le forum C
    Réponses: 3
    Dernier message: 12/12/2005, 19h24
  4. Erreur de division par 0 (MMX_FLAG)
    Par Harry dans le forum API, COM et SDKs
    Réponses: 3
    Dernier message: 23/09/2005, 11h47
  5. Erreur "Fichier utilisé par un autre processus"
    Par solo3326 dans le forum Langage
    Réponses: 3
    Dernier message: 18/08/2005, 16h55

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