Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1680 connectés 

  FORUM HardWare.fr
  Programmation
  C

  [C] Comment éviter les warnings pour "déclaration implicite de"

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C] Comment éviter les warnings pour "déclaration implicite de"

n°1871986
damien_ler​oy7
Posté le 10-04-2009 à 13:57:40  profilanswer
 

Bonjour à tous,  
 
Je suis en train de travailler sur un projet en C et j'ai quelques fois des warnings comme celui-ci :
 
Tokener.c:54: attention : déclaration implicite de la fonction « «isblank» »
 
Je ne comprends pas bien ce qu'il signifie et je ne sais forcément pas les corriger.  
 
Le programme semble pourtant se comporter comme voulu, mais je voudrais que ce code soit propre.
 
Pourriez-vous me renseigner?  
 
D'avance merci...
 
DL

Message cité 1 fois
Message édité par damien_leroy7 le 10-04-2009 à 13:58:15
mood
Publicité
Posté le 10-04-2009 à 13:57:40  profilanswer
 

n°1871993
olivthill
Posté le 10-04-2009 à 14:06:38  profilanswer
 

Est-ce que la fonction isblank() et ses lignes de code, se trouvent avant ou après l'appel à cette fonction ? Il semble que le code de isblank() se trouve après son appel (auquel cas il faudrait changer de place les lignes de code), ou qu'il se trouve dans un autre fichier, et qu'il manque une déclaration d'un "prototype" pour cette fonction (auquel cas il faudrait rajouter un prototype). Dans les tutoriels, voir le mot clé "prototype" de fonction.

n°1872017
jesus_chri​st
votre nouveau dieu
Posté le 10-04-2009 à 14:43:13  profilanswer
 

#include <ctype.h>
 
ça devrait mieux marcher.
En C il faut mettre les #include correspondants aux fonctions qu'on utilise. En cas de doute, mieux vaut en mettre trop que pas assez.
 
Par contre en C, au sens strict du langage, toute fonction qui retourne un entier peut être utilisée sans déclaration, d'où le fait que tu aies un warning et pas une erreur, mais c'est déconseillé.

n°1872076
Emmanuel D​elahaye
C is a sharp tool
Posté le 10-04-2009 à 16:44:46  profilanswer
 

damien_leroy7 a écrit :


Tokener.c:54: attention : déclaration implicite de la fonction « «isblank» »
 
Je ne comprends pas bien ce qu'il signifie et je ne sais forcément pas les corriger.  


Ca signifie que tu appelles une fonction sans avoir fourni de prototype au préalable. Le compilateur fait alors des hypothèses sur le type des paramètres et le retour. Il ne vérifie pas si le nombre de paramètres est conforme. Le comportement est donc indéterminé.
 
Pour coder correctement, il faut fournir un prototype. c'est le rôle des headers (.h) qui contiennent précisément les prototypes des fonctions.
 

Code :
  1. #include <ctype.h>



---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
n°1872092
jesus_chri​st
votre nouveau dieu
Posté le 10-04-2009 à 16:55:35  profilanswer
 

Emmanuel Delahaye a écrit :


Ca signifie que tu appelles une fonction sans avoir fourni de prototype au préalable. Le compilateur fait alors des hypothèses sur le type des paramètres et le retour. Il ne vérifie pas si le nombre de paramètres est conforme. Le comportement est donc indéterminé.
 
Pour coder correctement, il faut fournir un prototype. c'est le rôle des headers (.h) qui contiennent précisément les prototypes des fonctions.
 

Code :
  1. #include <ctype.h>




 
Le compilateur fait exactement une et une seule hypothèse : que le type de retour est entier.
Le comportement est determiné : la valeur de retour sera castée bit-à-bit depuis un entier. Les paramètres sont toujours bien passés, de toute façon en C on peut passer n'importe quoi en paramètre.

n°1872112
Emmanuel D​elahaye
C is a sharp tool
Posté le 10-04-2009 à 17:07:34  profilanswer
 

jesus_christ a écrit :


 
Le compilateur fait exactement une et une seule hypothèse : que le type de retour est entier.
Le comportement est determiné : la valeur de retour sera castée bit-à-bit depuis un entier. Les paramètres sont toujours bien passés, de toute façon en C on peut passer n'importe quoi en paramètre.


Et la marmotte ...

Code :
  1. #include <stdio.h>
  2. int main (void)
  3. {
  4.    print (123);
  5.    return 0;
  6. }
  7. void print (double x)
  8. {
  9.    printf ("%f\n", x);
  10. }



0.000000
 
Process returned 0 (0x0)   execution time : 0.084 s
Press any key to continue.


alors que

Code :
  1. #include <stdio.h>
  2. void print (double x);
  3. int main (void)
  4. {
  5.    print (123);
  6.    return 0;
  7. }
  8. void print (double x)
  9. {
  10.    printf ("%f\n", x);
  11. }



123.000000
 
Process returned 0 (0x0)   execution time : 0.023 s
Press any key to continue.


Message édité par Emmanuel Delahaye le 10-04-2009 à 17:08:50

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
n°1872215
damien_ler​oy7
Posté le 11-04-2009 à 10:31:57  profilanswer
 

Merci à tous pour ces informations utiles. En fait, je ne savais pas que isblank faisait partie de ctype.h
 
Encore un grand merci :)

n°1872227
el muchach​o
Comfortably Numb
Posté le 11-04-2009 à 11:41:16  profilanswer
 

L'exemple qui calme tout de suite...
 
Ceci dit, sur Visual Studio 2009, le premier ex. ne compile pas:
warning C4013: 'print' non défini(e) ; extern retournant int pris par défaut
error C2371: 'print' : redéfinition ; types de base différents

Message cité 2 fois
Message édité par el muchacho le 11-04-2009 à 11:52:12

---------------
Les aéroports où il fait bon attendre, voila un topic qu'il est bien
n°1872237
jesus_chri​st
votre nouveau dieu
Posté le 11-04-2009 à 12:39:52  profilanswer
 

el muchacho a écrit :

L'exemple qui calme tout de suite...
 
Ceci dit, sur Visual Studio 2009, le premier ex. ne compile pas:
warning C4013: 'print' non défini(e) ; extern retournant int pris par défaut
error C2371: 'print' : redéfinition ; types de base différents


 
Comme je l'avais dit, le compilateur suppose que c'est une fonction prenant des arguments arbitraires et retournant un entier. Par contre les casts d'arguments nécessaires ne sont pas faits, faute de connaître le bon type, un peu comme pour les arguments de printf, c'est le point qu'a révélé E.D.
 
Si VC2009 ne compile pas c'est parce qu'il applique certaines règles du C++ au C, le code de E.D. est tout a fait correct en C89.
De toute manière, il faut mettre les bons includes pour toutes les fonctions qu'on utilise.
Pour une ref sur les correspondances fonction/entête du C, voir :
http://www.ime.usp.br/~marioct/mac5710/ansic.html

n°1872239
Emmanuel D​elahaye
C is a sharp tool
Posté le 11-04-2009 à 12:59:46  profilanswer
 

el muchacho a écrit :

L'exemple qui calme tout de suite...
 
Ceci dit, sur Visual Studio 2009, le premier ex. ne compile pas:
warning C4013: 'print' non défini(e) ; extern retournant int pris par défaut
error C2371: 'print' : redéfinition ; types de base différents


Il ne compile pas en C++. Mais il compile en C. Attention à utiliser le bon compilateur. Pour être sûr : ajouter ceci au code source :  

Code :
  1. #ifdef __cplusplus
  2. #error Be sure you are using a C compiler...
  3. #endif



---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
mood
Publicité
Posté le 11-04-2009 à 12:59:46  profilanswer
 

n°1872244
Un Program​meur
Posté le 11-04-2009 à 13:23:51  profilanswer
 

jesus_christ a écrit :

Par contre en C, au sens strict du langage, toute fonction qui retourne un entier peut être utilisée sans déclaration,

 

En C90 et sous réserve qu'il n'y ait pas d'arguments variadiques ni d'un type qui serait promu quand on le passe à une fonction dont on n'a pas le prototype (char, short, float) et qu'on passe bien des arguments du bon type après promotion (Emmanuel a donné l'exemple d'une conversion int->double, il y a aussi NULL qu'il faut caster alors dans le bon type et, si on veut être strict, les implémentations où ça pose un problème étant rarissimes, les pointeurs à caster en void* si besoin est; c'est exactement les mêmes cas auxquels il faut faire attention dans les arguments variadiques).

 

En C99 les déclarations implicites de fonctions ne sont pas autorisées (gcc a besoin de -pedantic-error pour en faire une erreur en C99).

Message cité 3 fois
Message édité par Un Programmeur le 11-04-2009 à 13:26:09
n°1872249
Emmanuel D​elahaye
C is a sharp tool
Posté le 11-04-2009 à 14:21:07  profilanswer
 

Un Programmeur a écrit :

En C99 les déclarations implicites de fonctions ne sont pas autorisées (gcc a besoin de -pedantic-error pour en faire une erreur en C99).


Si, c'est autorisé (bien que fortement déconseillé, comme il a été démontré) . Ce qui ne l'est pas c'est le type retour implicite.
 
OK en C90, ne compile pas en C99 :  

Code :
  1. f()
  2. {
  3. }


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
n°1872258
Un Program​meur
Posté le 11-04-2009 à 16:32:38  profilanswer
 

Un Programmeur a écrit :


 
En C90 et sous réserve qu'il n'y ait pas d'arguments variadiques ni d'un type qui serait promu quand on le passe à une fonction dont on n'a pas le prototype (char, short, float) et qu'on passe bien des arguments du bon type après promotion (Emmanuel a donné l'exemple d'une conversion int->double, il y a aussi NULL qu'il faut caster alors dans le bon type et, si on veut être strict, les implémentations où ça pose un problème étant rarissimes, les pointeurs à caster en void* si besoin est; c'est exactement les mêmes cas auxquels il faut faire attention dans les arguments variadiques).
 
En C99 les déclarations implicites de fonctions ne sont pas autorisées (gcc a besoin de -pedantic-error pour en faire une erreur en C99).


 

Emmanuel Delahaye a écrit :


Si, c'est autorisé (bien que fortement déconseillé, comme il a été démontré) . Ce qui ne l'est pas c'est le type retour implicite.
 
OK en C90, ne compile pas en C99 :  

Code :
  1. f()
  2. {
  3. }



 
Tu as une référence?
 
J'ai les deux normes sous les yeux et le second alinéa de la section "Semantics" de 6.3.2.2 "Function calls" de C90:
 

Citation :

If the expression that precedes the parenthesized argument list in a function call consists solely of an identifier, and if no declaration is visible for this identifier, the identifier is implicitly declared exactly as if, in the innermost block containing the function call, the declaration
 
extern int identifier ();
 
appeared.


 
n'a pas d'équivalent dans 6.5.2.2.  Et je ne trouve nulle part ailleurs quelque chose d'équivalent.  Ca a pu m'échapper, mais jusqu'à preuve du contraire, je considère que ce n'est plus autorisé.   gcc donnant une erreur avec -std=c99 -pedantic-error, j'ai l'impression que ses auteurs ont la même interprétation.

n°1872262
el muchach​o
Comfortably Numb
Posté le 11-04-2009 à 16:50:28  profilanswer
 

Emmanuel Delahaye a écrit :


Il ne compile pas en C++. Mais il compile en C. Attention à utiliser le bon compilateur. Pour être sûr : ajouter ceci au code source :  

Code :
  1. #ifdef __cplusplus
  2. #error Be sure you are using a C compiler...
  3. #endif




OK. Effectivement, sous Visual Studio, j'ai pas trop cherché comment forcer le compiler à C. En tout cas, je vais certainement envoyer ton exemple à certains collègues qui ne prennent pas la peine de déclarer toutes leurs fonctions. :jap:


---------------
Les aéroports où il fait bon attendre, voila un topic qu'il est bien
n°1872265
jesus_chri​st
votre nouveau dieu
Posté le 11-04-2009 à 17:03:13  profilanswer
 

Un Programmeur a écrit :

[...]En C99 les déclarations implicites de fonctions ne sont pas autorisées [...]


Je dirais aussi que c'est toi qui a raison là.
Sun aussi a la même interprétation.
http://docs.sun.com/source/819-3688/c99.app.html#54208


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  [C] Comment éviter les warnings pour "déclaration implicite de"

 

Sujets relatifs
pointeur et fonction langage Cexercice pointeur et fonction langage C
exercice pointeur et fonction langage CC++ et pointeurs, problème pour désalouer...
[C] Initialisation d'un tableau constant[C] Parser un fichier texte
[C - librairie Gtk] mettre en place une GtkListStoreProblème avec allocation dynamique de tableau (C)
Plus de sujets relatifs à : [C] Comment éviter les warnings pour "déclaration implicite de"


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR