2009-10-29 12 views
1

Pourquoi est-ce codePourquoi avertissement en C et ne peut pas compiler en C++?

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

En C, me donner cet avertissement lors de la compilation:

'avertissement: attribution du type pointeur incompatible'

En C++, ne peut pas être en mesure de compiler .

+7

-t-il pas dit là dans le message d'avertissement quel est le problème? Les pointeurs pointent vers différents types .. :) – falstro

+0

+1 pour démontrer ce qu'est un « avertissement » signifie en C. –

+0

Je cherche réponse sur la façon dont fonctionne traducteur quand un rétrécissement implicite de int à carboniser. – root

Répondre

6

Les prototypes ne correspondent pas. g est un pointeur vers une fonction qui prend un int et renvoie un int tandis que h est un pointeur vers une fonction qui prend un char et renvoie un int. Ils sont deux types distincts et donc l'avertissement (attribution des pommes aux oranges).

2

On 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.

1

Vous avez déclaré que g est une fonction prenant un argument de type int et retournant un int, et h une fonction prenant un argument de type char et retournant un résultat int. Les deux signatures de fonction ne sont pas interchangeables et vous ne pouvez donc pas attribuer d'un pointeur à un pointeur à l'autre.

0

Vous avez déclaré g et h comme fonctions. En fait, mon compilateur donne l'erreur "lvalue required comme opérande gauche d'assignation", et il semble étrange que vous puissiez obtenir ce code pour compiler avec juste un avertissement?

EDIT: À l'origine, le code de la question déclarait g et h comme fonctions. Maintenant, ils ont été changés en pointeurs de fonction, ce qui ne fera que donner un avertissement.

3

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

Les pointeurs de fonction à la fois un retour int, tandis que g accepte un int comme entrée, et h accepte une carbonisation en tant que paramètres d'entrée.

Bien que vous pouvez parfois mélanger int et ombles, vous mélangez des pointeurs de fonction, de sorte que le compilateur vous donne correctement un avertissement que vous pourriez faire quelque chose de mal.

code Exemple:

#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; 
} 

Compiling:

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

programme en cours:

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

Comme vous le voyez, en C, cela fonctionne bien, mais le compilateur vous donne un avertissement approprié.Si nous essayons de le compiler comme le code C, le compilateur n'acceptera notre pointeur jonglerie:

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

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

ignorer les avertissements, utilisez les pointeurs de fonction (pendant l'incantation pour qu'il compile en fait) et vous verrez ce que je veux dire :)

+0

@dirkgently: noté et édité. –

0

Depuis les signatures de fonction sont différentes, ce n'est pas juridique C ou juridique C++. La question est pourquoi les compilateurs traitent différemment. Dans les deux cas, il n'y a pas beaucoup d'indications sur ce qu'il faut faire avec les programmes qui violent la norme, sauf que certaines violations nécessitent un diagnostic (et ces deux cas fournissent un message de diagnostic). Les standards sont normalement concernés par ce qu'est un programme C ou C++ valide, et ce que l'implémentation doit faire quand on en a un.

C est un langage beaucoup plus que C++, et beaucoup de code C a été écrit sur les compilateurs beaucoup moins strictes que celles qui existent de nos jours. C++ était plus strict dès le début, et donc le code C++ pré-standard a tendance à être un code C++ standard valide qui n'utilise pas certaines fonctionnalités.

Pour cette raison, un compilateur C est plus susceptible d'être clémente 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 certaines d'entre elles sont très utiles, mais il n'en va pas de même pour C++.

0

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