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 :

Comment déboguer called object ‘commande’ is not a function or function pointer?


Sujet :

C

  1. #1
    Membre confirmé
    Homme Profil pro
    Etudiant
    Inscrit en
    Novembre 2015
    Messages
    156
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Etudiant

    Informations forums :
    Inscription : Novembre 2015
    Messages : 156
    Par défaut Comment déboguer called object ‘commande’ is not a function or function pointer?
    Bonjour!

    Voilà, je sais, c'est censé être un indice d'une erreur bête mais je viens de rencontrer:

    error: called object ‘commande’ is not a function or function pointer


    J'implore votre pitié, je ne trouve pas l'erreur bête, pouvez-vous m'aider, Ô nobles développeurs?
    J'ai épluché mon code ainsi que des pages web de personnes ayant eu une erreur similaire, je ne vois pas d'où la mienne peut bien venir...

    Il s'agit du code d'un shell UNIX recréé à la main à partir de rien...

    L'erreur en entier:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    copp@b032-26:~$ projet.c: In function ‘main’:
    projet.c:142:22: error: called object ‘commande’ is not a function or function pointer
       commande = commande();
                          ^
    projet.c:138:6: note: declared here
      int commande = 0;
    et mon code:

    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    int commande(){
    	parsing();
    	switch(symboleP){
    	int pid;
    	case 0:// \n
     
    	case 1:// ;
     
    		pid = fork();
     
    		if(pid > 0){
    			int valeurWait = wait(&status);// Cette instruction suspend le processus père jusqu'à ce qu'un des processus fils se termine, elle retourne  le pid du  processus  qui  s'est  terminé  et  l'état du  processus terminé  est  placé  à l'adresse &status.
    			if(WIFEXITED(status) == 0){
     
    				return 0;
    			}	
     
    		}else if(pid == 0){
     
    			execvp(respP[0],respP);
    		}else{
    			printf("erreur de pid");		
    		}
     
    		break;
     
    		case 2: // &
    		//*com[i++]=0;*//
    		pid=fork();
    		/*
    		Mettre un if pour que le pere observe le fils
    		le exec sera dans le fils
    		*/
    		if(pid>0){
    /*		        if (background==0) {
    		        int valeurWait = wait(&status);
    			} else {
    				/*
    				A la fin de l execution normale du fils, on retourne vers le processsus pere
    				le return 0 permet d'afficher le prompt Dauphine> conformement au switch du main.c
    				*/
    				//i=0;
    				return 1;
     
    		} else {
    			return 7;
    		}
    		break;
     
    	case 3: // <
     
    	if(pid>0){
    /*		        if (background==0) {
    		        int valeurWait = wait(&status);
    			} else {
    				/*
    				A la fin de l execution normale du fils, on retourne vers le processsus pere
    				le return 0 permet d'afficher le prompt Dauphine> conformement au switch du main.c
    				*/
    				//i=0;
    				return 1;
     
    		} else {
    			return 7;
    		}
    		break;
    	}
     
    	return 0;
    }
     
     
    int main(){
    	int commande = 0;
    	printf("Dauphine>");
    	fflush(stdout); //Pour vider le buffer et forcer l'execution de la commande mais je n'en sais pas plus..!
    	while(1){
    		commande = commande();
    		switch(commande){
    			case 7: // EOF
    			return 0;
     
    			case 0: // CR
    			printf("Dauphine>");
    			fflush(stdout);
    			break;
    		}
    		fflush(stdout);
    	}
     
    	return 0;
    }

  2. #2
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    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 202
    Par défaut
    comme ce n'est pas une déclaration (il n'y a pas de type devant la variable commande), l'identifieur commande est le même partout dans l'expression.
    En fait tu essaie d'appeler la variable commande comme une fonction.

    La raison vient probalblement de ce que tu as déclaré la variable trop tot. Et encore plus probablement de ce qu'elle devrait s'appeler statut_execution.

  3. #3
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 442
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 442
    Par défaut
    Citation Envoyé par leternel Voir le message
    comme ce n'est pas une déclaration (il n'y a pas de type devant la variable commande), l'identifieur commande est le même partout dans l'expression.
    En fait tu essaie d'appeler la variable commande comme une fonction.
    En fait, il y a bien une une déclaration de variable (en ligne 74) mais il y a également une déclaration de fonction (en ligne 1), les deux portant le même nom.

    Citation Envoyé par AntoineCompagnie Voir le message
    J'implore votre pitié, je ne trouve pas l'erreur bête, pouvez-vous m'aider, Ô nobles développeurs?
    J'ai épluché mon code ainsi que des pages web de personnes ayant eu une erreur similaire, je ne vois pas d'où la mienne peut bien venir...
    En C, tu ne peux pas t'appuyer sur la signature d'un identifiant pour distinguer deux objets homonymes.

    Lorsque tu invoques — seul — l'identifiant d'une fonction, celui-ci est résolu en l'adresse en mémoire du point d'entrée du code machine correspondant à la fonction (comprendre : « là où il faut l'appeler »), c'est-à-dire en un pointeur de fonction. Le fait d'ajouter des parenthèses à la suite d'un pointeur de fonction, quel qu'il soit, éventuellement garnies de paramètres, permet d'appeler cette fonction en lui passant les paramètres en question s'ils existent (via la pile). C'est donc la manière normale d'appeler les fonctions ordinaires, mais également celles qui sont transmises via des pointeurs de fonctions déclarés comme tels, par exemple dans le cas des fonctions de callback ou bibliothèques dynamiques chargées a posteriori par dlopen().

    Si tu définis ensuite une variable locale portant le même nom qu'une fonction (globale, donc), il va se passer la même chose qu'avec les variables globales ou locales de plus haut niveau : l'identifiant va « masquer » les identifiants préalablement déclarés dans le bloc où elle l'est.

    Quand tu tapes « commande = commande() », tu te réfères donc à la même variable à gauche et à droite du signe « = ». C'est légal mais à droite, tu essaies d'invoquer une variable locale de type int comme une fonction, ce qu'elle n'est pas. D'où l'erreur.

  4. #4
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    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 202
    Par défaut
    j'entendais par la que l'instruction int commande = commande(); aurait fonctionné.
    En effet, l'identifieur n'est considéré déclaré qu'après l'initialisation, et donc ne masque pas encore un homonyme utilisé dans l'initialisation.

    Edit: en fait, c'est faux.

  5. #5
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 442
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 442
    Par défaut
    Citation Envoyé par leternel Voir le message
    j'entendais par la que l'instruction int commande = commande(); aurait fonctionné.
    En effet, l'identifieur n'est considéré déclaré qu'après l'initialisation, et donc ne masque pas encore un homonyme utilisé dans l'initialisation.
    C'est effectivement un cas de figure intéressant, mais ça ne fonctionne pas sous GCC :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #include <stdio.h>
     
    int command()
    {
        return 5;
    }
     
    int main (void)
    {
        int command = command();
     
        printf ("%d\n",command);
     
        return 0;
    }

    Code Shell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $ gcc command.c -o command
    command.c: Dans la fonction ‘main’:
    command.c:10:19: erreur: called object ‘command’ is not a function or function pointer
         int command = command();
                       ^
    command.c:10:9: note: declared here
         int command = command();

    L'identifiant existe dès la déclaration et masque tout de suite le reste, d'abord parce qu'il n'est pas obligatoire d'initialiser une variable quand on la déclare, ensuite parce qu'il est tout-à-fait autorisé de s'auto-référencer, y compris à l'initialisation. Ainsi, ce qui suit est valable :

    Par ailleurs, il est parfois nécessaire de pouvoir faire des déclarations partielles, par exemple quand deux structures A et B se référencent mutuellement par pointeur interposé.

  6. #6
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    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 202
    Par défaut
    Merci pour la vérification.
    Je n'ai plus qu'à réviser.

    J'ai pourtant lu quelque chose dans ce genre. Peut-être en C++, et encore.

  7. #7
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 442
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 442
    Par défaut
    Citation Envoyé par leternel Voir le message
    J'ai pourtant lu quelque chose dans ce genre. Peut-être en C++, et encore.
    En C++, c'est possible dans une certaine mesure justement pour les raisons exposées au dessus : la signature associée aux identifiants. Le C++ permet la surcharge de fonctions, c'est-à-dire la possibilité de référencer deux portions de code différentes selon le type des paramètres passés ou non, le détail des paramètres venant en fait s'ajouter au nom de la fonction proprement dite, en faisant un identifiant dit « décoré ».

    Le distingo peut se faire à ce niveau mais le problème reste le même : étant donné qu'il est possible d'invoquer n'importe quel symbole comme une fonction en évaluant l'identifiant comme un pointeur de fonction (fût-ce au travers d'un transtypage), l'ambiguïté demeure et on ne peut pas décider à quel objet on fait référence. Il est cependant possible de se référer à un objet défini au niveau global (variable ou fonction) par rapport à un objet local, en utilisant l'opérateur de portée. On peut écrire ceci :

    Code C++ : 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
    #include <iostream>
     
    using namespace std;
     
    int commande()
    {
        return 1;
    }
     
    int main (void)
    {
        int commande = ::commande();
     
        cout << commande << endl;
     
        return 0;
    }

    … grâce aux « :: », mais il ne serait pas possible de définir « int commande » en tant que variable globale.

  8. #8
    Membre confirmé
    Homme Profil pro
    Etudiant
    Inscrit en
    Novembre 2015
    Messages
    156
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Etudiant

    Informations forums :
    Inscription : Novembre 2015
    Messages : 156
    Par défaut
    Merci beaucoup, j'ai suivi vos conseils et j'ai rennomé la variable en question.
    Je ne savais pas que ca ne pouvait pas marcher de cette manière...

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

Discussions similaires

  1. Comment gérer les objects déclarer en HTML dans un script JAVASCRIPT?
    Par Thauglor dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 25/04/2006, 14h54
  2. Comment savoir combien de personnes ont noté un sujet?
    Par NicolasG dans le forum Mode d'emploi & aide aux nouveaux
    Réponses: 4
    Dernier message: 18/04/2006, 09h23
  3. Comment déboguer une DLL??
    Par Mickey.jet dans le forum EDI
    Réponses: 5
    Dernier message: 30/03/2006, 08h50
  4. Réponses: 2
    Dernier message: 30/01/2004, 14h07
  5. [VB6] comment savoir si la commande shell est terminée ?
    Par ghyscharlotte dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 30/07/2003, 19h12

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