Frage

Warum funktioniert dieser Code

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

In C, geben Sie mir eine solche Warnung beim Kompilieren:

'Warnung: Zuordnung von inkompatiblen Zeigertyp'

In C ++ kann nicht in der Lage sein, zu kompilieren.

War es hilfreich?

Lösung

Prototypen stimmen nicht überein. g ist ein Zeiger auf eine Funktion, die eine int nimmt und gibt eine int h während ein Zeiger auf eine Funktion ist, die eine char nimmt und gibt eine int. Sie sind zwei getrennte Arten und damit die Warnung (Äpfel mit Orangen zuweisen).

Andere Tipps

Die beiden Funktionen Zeiger haben nicht die gleiche Signatur, da die Eingangsparameter unterschiedlich sind.

Die Funktionszeiger beide zurückgeben ein int , während g akzeptiert eine int als Eingabe und h akzeptiert a char als Eingangsparameter.

Sie können zwar manchmal mischen int und char , Sie Funktionszeiger mischen, so dass der Compiler korrekt gibt Ihnen eine Warnung, dass Sie etwas falsch zu machen könnte.

Beispielcode:

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

Compilieren:

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

Beim Laufen Programm:

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

Wie Sie sehen, in C, es funktioniert gut, aber der Compiler gibt Ihnen eine korrekte Warnung. Wenn wir versuchen, dies als C ++ Code zu kompilieren, wird der Compiler nicht unseren Zeiger Jonglieren akzeptieren:

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

Man wird erklärt auf eine Funktion zum Punkt ein int akzeptieren, die andere - auf eine Funktion, einen char zu akzeptieren. Das sind unterschiedliche Signaturen, so dass die Zeiger sind nicht kompatibel.

Sie haben erklärt g eine Funktion ein Argument vom Typ int und Zurückkehren eines int zu sein, und h eine Funktion ein Argument vom Typ char und Zurücksenden eines int Ergebnis. Die beiden Funktionssignaturen sind nicht austauschbar und so kann man nicht von einem Zeiger auf ein auf einen Zeiger auf den anderen übertragen.

Sie haben g und h als Funktionen erklärt. Eigentlich gibt meinen Compiler den Fehler „L-Wert als linken Operanden Zuordnung erforderlich“, und es scheint seltsam, dass Sie diesen Code nur mit einer Warnung zu kompilieren bekommen?

EDIT: Ursprünglich der Code in der Frage erklärt g und h als Funktionen. Jetzt haben sie auf Funktionszeiger geändert worden, was wird in der Tat nur eine Warnung aus.

Weil Sie inkompatible Zeiger zuweisen. Ein Funktionszeiger nimmt eine Ganzzahl mit Vorzeichen als Argument, das andere char (Signedness auf Ihrem System abhängt). Auch wenn beide gleich zurückkehren, sind sie ganz anders aus.

die Warnungen ignorieren, verwenden Sie die Funktionszeiger (beim Wirken von Zaubern, um es tatsächlich zu kompilieren), und Sie werden sehen, was ich meine:)

Da die Funktion Signaturen unterschiedlich sind, ist dies nicht legal C oder juristische C ++. Die Frage ist, warum die Compiler es anders behandeln. In keinem der beiden Standard gibt es viel Anleitung, was mit den Programmen zu tun, die den Standard verletzen, mit der Ausnahme, dass bestimmte Verstöße eine diagnostische erfordern (und beide dieser Fälle eine Diagnosemeldung beliefern). Die Standards werden in der Regel mit dem, was einer gültigen C oder C ++ Programm ist, und das, was die Umsetzung zu tun hat, wenn man gegeben.

C ist eine wesentlich ältere Sprache als C ++, und eine ganze Menge von C-Code wurde viel weniger streng Compiler geschrieben als heutzutage existiert. C ++ war von Anfang an strengen, und so Vornorm C ++ Code neigt gültige Standard C ++ Code zu sein, die nicht nur bestimmte Funktionen nicht verwendet.

Aus diesem Grund wird ein C-Compiler ist eher nachsichtig sein als ein C ++ Compiler, vorausgesetzt, die Compiler für den praktischen Gebrauch geschrieben wurden. Immerhin gibt es eine Menge von C-Code, der ungeniert Dinge wie diese Arbeit übernimmt, und einiges davon ist sehr nützlich, aber das gleiche gilt nicht für C ++.

Was ich hinzufügen kann, ist, dass Funktionsanpassung in C anders als in C ++. In C Sie nur den Namen verwenden (also Parameter Überlastung ist nicht möglich). In C ++ Jede Funktion hat, einen anderen „Signatur“, die aus params bestand. (Sie hatten Parameter Überlastung zu realisieren.).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top