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 :

l'expression doit avoir un type arithmétique ou pointeur


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 54
    Par défaut l'expression doit avoir un type arithmétique ou pointeur
    Bonjour,

    Lors de la réalisation d'un exercice, je suis tombé sur une erreur que je ne comprend pas.

    J'ai trouvé la solution, mais je n'en comprend pas la raison.

    J'ai donc une fonction de type int depuis laquelle je retourne une valeur:

    Le prototype de ma fonction

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int init_stGestMsg(int *pRC);
    L'appel depuis le main

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    	if (init_stGestMsg(&pRC) == GM_ERROR)
    	{
    		puts(GM_INIT_ERROR);
    	}
    	else
    	{
    		puts(GM_INIT_OK);
    	}

    et la fonction
    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
     
    int init_stGestMsg(int *pRC)
    {
     
     
    	// -------------------------------------------------------------------------------------------------------
    	// Initialisation des variables
    	etGestMsg stGestMsg = {NULL, 0, 5};
     
    	stGestMsg.dTailleBlocMax = stGestMsg.dTailleBloc;
     
    	// -------------------------------------------------------------------------------------------------------
    	// Création du tableau de messages TabMsg
    	if ((stGestMsg.tTabMsg = malloc(stGestMsg.dTailleBloc * sizeof(char*))) == NULL)
    	{
    		return GM_ERROR;
    	}
    	else
    	{
    		return GM_OK;
    	}
     
    }

    jusque la tout va bien..

    Mais en relisant l'exercice demandé par le prof, je m’aperçois qu'il demande à ce que la fonction soit de type void.

    du coup j’édite le type de la fonction avec un void et je fais les modif dans la fonction comme ceci

    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
    void init_stGestMsg(int *pRC)
    {
     
     
    	// -------------------------------------------------------------------------------------------------------
    	// Initialisation des variables
    	etGestMsg stGestMsg = {NULL, 0, 5};
     
    	stGestMsg.dTailleBlocMax = stGestMsg.dTailleBloc;
     
    	// -------------------------------------------------------------------------------------------------------
    	// Création du tableau de messages TabMsg
    	if ((stGestMsg.tTabMsg = malloc(stGestMsg.dTailleBloc * sizeof(char*))) == NULL)
    	{
    		*pRC = GM_ERROR;
    	}
    	else
    	{
    		*pRC = GM_OK;
    	}
     
    }
    et j'ai l'erreur dans le main dont je parlais et que je ne comprend pas ou il souligne ma fonction en rouge et me dit que "l'expression doit avoir un type arithmétique ou pointeur"

    La solution que j'ai trouvé est d'ajouter une * apres le void dans le prototype

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void * init_stGestMsg(int *pRC);
    et de faire de même dans le fichier de la fonction évidemment..

    En chipotant, je me rend compte que c'est a cause de l'inclusion de l'appel de fonction dans mon If
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (init_stGestMsg(&pRC) == GM_ERROR)
    que cela pose problème, et que si j'appelle la fonction en dehors du If, je n'ai pas besoin de rajouter l'* après le void..

    Et c'est la qu'est ma question.. Pourquoi???

  2. #2
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Une fonction retournant void ne retourne...... rien. Tu ne peux pas comparer ce qu'elle retourne à quelque chose si ta fonction ne retourne rien ! Pourtant, c'est ce que tu fais ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (init_stGestMsg(&pRC) == GM_ERROR)
    Si en revanche ta fonction retourne void*, alors elle ne renvoie pas rien : elle renvoie un pointeur*. Tu peux donc comparer ton pointeur à quelque chose.

    Néanmoins, je suis étonné que ton compilateur n'émette pas d'autres warnings. Comment compiles-tu ? Quelle option passes-tu à ton compilateur ?

    *: si "rien" est désigné par "void", il ne faut pas croire que "void*" est un pointeur sur rien. C'est un pointeur sur quelque chose dont on ne précise pas le type. "void*" est un type spécial en C permettant de retourner un pointeur sur tout et n'importe quoi

  3. #3
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 54
    Par défaut
    Ah ok.. je me doutais que ca devait etre lié au If et a la comparaison du resutlat de la fonction.. mais je n'en étais pas sur.

    J'utilise VS 2017 et l'exercice se fait en C
    La seule option que je configure quand je crée un projet, c'est de changer le "Compiler en " -> "Compiler en code C (/TC)" dans les options avancées C/C++ des propriétés du projet.
    Et je n'ai aucune erreur de compil ou d'avertissements.
    Est ce que ca devrait??

    Est ce que ma façon de faire pourrait poser problème, peut être pas dans cette exercice en particulier mais dans des prg plus complexe??
    Est ce que de manière générale il vaut mieux séparer un appel de fonction et ensuite passer l'argument a un If??

    Si ca n'est pas une bonne méthode de dev, je préfère le savoir maintenant

    edit.. j'ai bien des warnings en fait

    1>fct_GestMsg.c
    1>...\gestionnaire_message.v2\fct_gestmsg.c(111): warning C4047: '=='*: les niveaux d'indirection de 'int' et de 'void *' sont différents
    1>...\\gestionnaire_message.v2\fct_gestmsg.c(106): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
    1>c:\program files (x86)\windows kits\10\include\10.0.14393.0\ucrt\string.h(129): note: voir la déclaration de 'strcpy'
    1>>...\\gestionnaire_message.v2\fct_gestmsg.c(75): warning C4716: 'init_stGestMsg' : doit retourner une valeur
    1>>...\\gestionnaire_message.v2\fct_gestmsg.c(121): warning C4716: 'gAddMsg' : doit retourner une valeur
    1>>...\\gestionnaire_message.v2\gestionnaire_message.v2\fct_gestmsg.c(160): warning C4716: 'afficheMsg' : doit retourner une valeur
    1>Gestionnaire_Message.V2.vcxproj -> >...\\Debug\Gestionnaire_Message.V2.exe
    1>Gestionnaire_Message.V2.vcxproj -> >...\\Debug\Gestionnaire_Message.V2.pdb (Partial PDB)
    1>Génération du projet "Gestionnaire_Message.V2.vcxproj" terminée.
    ========== Génération*: 1 a réussi, 0 a échoué, 0 mis à jour, 0 a été ignoré ==========

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    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 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Dunkhan Voir le message
    edit.. j'ai bien des warnings en fait
    Bonjour

    Un warning est un message signifiant "je ne suis pas certain d'avoir bien compris alors je vais tenter de coder ce que moi je comprends mais sans garantie". Ca ne veut pas dire que ça ne fonctionnera pas... mais ça ne garantit pas non plus que ça fonctionnera.
    Donc il vaut mieux faire en sorte de les supprimer...
    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]

  5. #5
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 54
    Par défaut
    Moi qui pensait avoir trouvé un moyen d'optimiser mon code.. :/

  6. #6
    Membre Expert
    Avatar de Pyramidev
    Homme Profil pro
    Tech Lead
    Inscrit en
    Avril 2016
    Messages
    1 513
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Tech Lead

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 513
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Un warning est un message signifiant "je ne suis pas certain d'avoir bien compris alors je vais tenter de coder ce que moi je comprends mais sans garantie".
    Si on prend l'exemple « 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. », on ne peut pas dire que le compilateur n'est pas certain d'avoir compris.

    @Dunkhan,

    Un avertissement, c'est « J''accepte de compiler ce code. Mais, attention, on dirait qu'il contient des erreurs de programmation. »
    Parfois, c'est un faux positif. Par exemple, peut-être que, avant l'appel à strcpy(dest, src), tu as bien pris le soin de vérifier que strlen(str) était bien strictement inférieur au nombre de bytes dans le tampon pointé par dest.
    Mais il faut quand même se débrouiller pour que le code ne génère plus d'avertissements. Sinon, si on a 500 avertissements qui correspondent à des faux positifs, le jour où il y aura une vraie erreur de programmation détectée par un avertissement, ce nouvel avertissement sera noyé parmi les 500 avertissements et ne sera pas lu.

    S'aider des avertissements du compilateur pour détecter de potentielles erreurs de programmations permet d'éviter des bogues stupides comme celui-ci : https://www.developpez.com/actu/1222...t-open-source/
    Dans l'article dont j'ai donné le lien, la faille critique de sécurité venait d'un bogue qui venait d'une instruction zccoinSpend.denomination == libzerocoin::ZQ_WILLIAMSON; dans laquelle == aurait du être un =.
    Je ne sais pas quel(s) compilateur(s) les développeurs du projet utilisaient mais, avec GCC, avec l'option -Wall, une telle instruction provoque un avertissement « warning: equality comparison result unused ».

  7. #7
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 54
    Par défaut
    D'accord..
    Merci pour les précisions et l'article.

    Du coup je me demandais si il y avait moyen de formuler mon if pour ne pas déclencher ce genre de warning?

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

Discussions similaires

  1. Réponses: 146
    Dernier message: 05/10/2012, 17h47
  2. Réponses: 3
    Dernier message: 14/08/2007, 22h58
  3. distinct doit avoir une position particulière?
    Par robert_trudel dans le forum Access
    Réponses: 1
    Dernier message: 11/08/2006, 08h15
  4. Compilation avec Visual C++ 2005 Express pour avoir un module python
    Par Freyja dans le forum Déploiement/Installation
    Réponses: 6
    Dernier message: 13/07/2006, 12h12
  5. quel format doit avoir une BD pour l'importer avec copy?
    Par daknoom dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 03/02/2005, 19h41

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