Domanda

Perché questo codice

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

In C, dammi tale avviso durante la compilazione:

"avviso: assegnazione da un tipo di puntatore incompatibile"

In C ++, non è possibile compilare.

È stato utile?

Soluzione

I prototipi non corrispondono. g è un puntatore a una funzione che accetta un int e restituisce un int mentre h è un puntatore a un funzione che accetta un char e restituisce un int . Sono due tipi separati e quindi l'avvertimento (assegnazione delle mele alle arance).

Altri suggerimenti

I due puntatori di funzioni non hanno la stessa firma, poiché i parametri di input sono diversi.

I puntatori a funzione restituiscono entrambi un int , mentre g accetta un int come input e h accetta un carattere come parametri di input.

Anche se a volte puoi mescolare int e char , stai mescolando i puntatori a funzione, quindi il compilatore ti avvisa correttamente che potresti fare qualcosa di sbagliato.

Codice di esempio:

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

Compilazione:

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

Programma in esecuzione:

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

Come vedi, in C, funziona bene, ma il compilatore ti dà un avviso adeguato. Se proviamo a compilare questo come codice C ++, il compilatore non accetterà il nostro giocoleria puntatore:

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

Uno è dichiarato che punta a una funzione che accetta un int , l'altro - a una funzione che accetta un char . Quelle sono firme diverse, quindi i puntatori sono incompatibili.

Hai dichiarato g come una funzione che prende un argomento di tipo int e restituisce un int, e h come una funzione che prende un argomento di tipo char e restituisce un risultato int. Le firme delle due funzioni non sono intercambiabili e quindi non è possibile assegnare da un puntatore a uno a un puntatore all'altro.

Hai dichiarato geh come funzioni. In realtà, il mio compilatore fornisce l'errore "lvalue richiesto come operando di sinistra dell'assegnazione", e sembra strano che tu possa ottenere questo codice da compilare con un solo avvertimento?

EDIT: originariamente, il codice nella domanda dichiarava ge h come funzioni. Ora sono stati cambiati in puntatori a funzione, che in effetti daranno solo un avvertimento.

Perché stai assegnando puntatori incompatibili. Un puntatore a funzione accetta un intero con segno come argomento, l'altro carattere (la firma dipende dal sistema). Anche se entrambi restituiscono lo stesso, sono abbastanza diversi.

Ignora gli avvisi, usa i puntatori di funzione (mentre esegui il casting per renderlo effettivamente compilato) e vedrai cosa intendo :)

Poiché le firme delle funzioni sono diverse, non si tratta di C legale o C ++ legale. La domanda è: perché i compilatori la trattano diversamente. In nessuno degli standard c'è molta guida su cosa fare con i programmi che violano lo standard, tranne per il fatto che alcune violazioni richiedono una diagnostica (ed entrambi questi casi forniscono un messaggio diagnostico). Gli standard riguardano normalmente cos'è un programma C o C ++ valido e cosa deve fare l'implementazione quando ne viene dato uno.

C è un linguaggio notevolmente più vecchio di C ++, e un sacco di codice C è stato scritto su compilatori molto meno rigidi di quelli esistenti al giorno d'oggi. Il C ++ è stato più rigoroso dall'inizio, quindi il codice C ++ pre-standard tende ad essere un codice C ++ standard valido che semplicemente non utilizza determinate funzionalità.

Per questo motivo, è più probabile che un compilatore C sia clemente rispetto a un compilatore C ++, supponendo che i compilatori siano stati scritti per uso pratico. Dopotutto, c'è molto codice C che assume allegramente cose come questa, e alcune di queste sono molto utili, ma lo stesso non è vero per C ++.

Quello che posso aggiungere è che la corrispondenza delle funzioni in C è diversa da quella in C ++. In C si utilizza solo il nome (pertanto non è possibile sovraccaricare i parametri). In C ++ ogni funzione ha una "firma" diversa, composta dai parametri. (Hanno dovuto rendersi conto del sovraccarico dei parametri.)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top