Question

Pourquoi ce code

int (*g)(int);
int (*h)(char);
h = g;

En C, donnez-moi un tel avertissement lors de la compilation:

'avertissement: affectation provenant d'un type de pointeur incompatible'

En C ++, impossible de compiler.

Était-ce utile?

La solution

Les prototypes ne correspondent pas. g est un pointeur sur une fonction qui prend un int et renvoie un int alors que h est un pointeur sur un fonction qui prend un char et retourne un int . Ce sont deux types distincts et donc l’avertissement (attribuer des pommes à des oranges).

Autres conseils

Les deux pointeurs de fonctions n'ont pas la même signature car les paramètres d'entrée sont différents.

Les pointeurs de fonction renvoient tous deux un int , tandis que g accepte un int en entrée et h accepte un caractère en tant que paramètre d'entrée.

Bien que vous puissiez parfois mélanger int et char , vous mélangez des pointeurs de fonction. Le compilateur vous avertit donc correctement que vous faites peut-être quelque chose de mal.

Exemple de code:

#include <stdio.h>

int gf(int n)
{
    return printf("gf(%d)\n", n);
}

int hf(char c)
{
    return printf("hf('%c')\n", c);
}

int main()
{
    int (*g)(int) = gf; // pointer to gf
    int (*h)(char) = hf; // pointer to hf

    g = h; // warning: possibly incompatible functions

    g(65); // cast 65 to char and call h

    return 0;
}

Compilation:

$ gcc-4.exe -Wall a.c
a.c: In function 'main':
a.c:18: warning: assignment from incompatible pointer type

Programme en cours d'exécution:

$ ./a.exe
hf('A')

Comme vous le voyez, en C, cela fonctionne bien, mais le compilateur vous avertit correctement. Si nous essayons de le compiler en code C ++, le compilateur n'acceptera pas notre jonglerie de pointeur:

$ g++-4.exe a.c
a.c: In function 'int main()':
a.c:18: error: invalid conversion from 'int (*)(char)' to 'int (*)(int)'

L'un est déclaré pointer vers une fonction acceptant un int , l'autre - vers une fonction acceptant un char . Ce sont des signatures différentes, donc les pointeurs sont incompatibles.

Vous avez déclaré que g était une fonction prenant un argument de type int et renvoyant un int, et que h était une fonction prenant un argument de type char et renvoyant un résultat int. Les deux signatures de fonction ne sont pas interchangeables et vous ne pouvez donc pas assigner un pointeur à un pointeur vers un autre.

Vous avez déclaré g et h en tant que fonctions. En fait, mon compilateur donne l’erreur "Valeur requise en tant qu’opérande gauche de la tâche", et il semble étrange que vous puissiez obtenir ce code à compiler avec juste un avertissement?

EDIT: A l’origine, le code de la question déclarait g et h en tant que fonctions. Maintenant, ils ont été remplacés par des pointeurs de fonction, ce qui n’est en fait qu’un avertissement.

Parce que vous assignez des pointeurs incompatibles. Un pointeur de fonction prend un entier signé en argument, l'autre caractère (la signature dépend de votre système). Même si les deux retournent la même chose, ils sont très différents.

Ignorez les avertissements, utilisez les pointeurs de fonction (lors de la compilation pour le compiler réellement) et vous verrez ce que je veux dire:)

Étant donné que les signatures de fonction sont différentes, il ne s'agit ni de C légal ni de C ++ légal. La question est de savoir pourquoi les compilateurs le traitent différemment. Aucune de ces normes ne contient beaucoup d'indications sur l'utilisation des programmes qui ne respectent pas cette norme, à l'exception du fait que certaines violations nécessitent un diagnostic (et que ces deux cas fournissent un message de diagnostic). Les normes concernent normalement ce qu’est un programme C ou C ++ valide et ce que l’implémentation doit faire quand on en donne un.

C est un langage considérablement plus ancien que C ++ et beaucoup de code C a été écrit sur des compilateurs beaucoup moins stricts qu’aujourd’hui. C ++ était dès le début plus strict et donc le code C ++ pré-standard tend à être un code C ++ standard valide qui n’utilise tout simplement pas certaines fonctionnalités.

Pour cette raison, un compilateur C est plus susceptible d'être indulgent qu'un compilateur C ++, en supposant que les compilateurs ont été écrits pour une utilisation pratique. Après tout, il y a beaucoup de code C qui suppose allègrement des choses comme ce travail, et une partie de cela est très utile, mais ce n'est pas le cas du C ++.

Ce que je peux ajouter, c’est que la correspondance des fonctions en C est différente de celle en C ++. En C, vous n’utilisez que le nom (la surcharge de paramètres n’est donc pas réalisable). En C ++, chaque fonction a une "signature" différente, composée à partir des paramètres. (Ils devaient réaliser une surcharge de paramètres.)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top