2015-10-27 12 views
8

Ich habe Code, der unter GCC 4.8.4 gut kompiliert wurde. Ich habe kürzlich mein System aktualisiert und habe jetzt GCC 5.2.1, und ich bekomme eine Warnung über inkompatible Zeigertypen. Ich habe das Problem auf ein kleines Beispiel extrahiert, die den Fehler reproduziert:GCC Inkompatibler Zeigertyp mit typedef

typedef const double ConstSpiceDouble; 
void foo(const double (*)[3]); 

int main(int argc, char **argv) { 
    double a[3][3] = {{1,2,3},{1,2,3},{1,2,3}}; 

    foo((ConstSpiceDouble (*)[3])a); 

    return 0; 
} 

In dem realen Code, der typedef, die Funktionsdefinition und die Typumwandlung ist in einer Bibliothek außerhalb meiner Kontrolle sonst würde ich nur Korrigieren Sie den Cast und die passende Funktion. Hier ist die Botschaft, die ich aus dem Compiler erhalten:

$ gcc -Werror -c test.c 
test.c: In function ‘main’: 
test.c:9:7: error: passing argument 1 of ‘foo’ from incompatible pointer type [-Werror=incompatible-pointer-types] 
    foo((ConstSpiceDouble (*)[3])a); 
    ^
test.c:4:6: note: expected ‘const double (*)[3]’ but argument is of type ‘const ConstSpiceDouble (*)[3] {aka const double (*)[3]}’ 
void foo(const double (*)[3]); 
    ^
cc1: all warnings being treated as errors 

Die Notiz von gcc ist besonders beunruhigend, da es zugeben scheint, dass die beiden Typen identisch sind, aber es beschwert sich trotzdem.

+4

Kompiliert ohne Probleme auf [GCC 5.2.0] (http://coliru.stacked-crooked.com/a/f7768e128db5462b) (und auch Clang 3.7.0). Ich lehne mich einem Compiler-Bug zu. – Quentin

+0

Gut zu wissen, dass es unter 5.2.0 kompiliert wird, was die Versionsmöglichkeiten auf 5.2.1 beschränkt. – Gravatite

+0

Was meinen Sie, wenn Sie "5.2.1" sagen? Diese Version ist noch nicht offiziell freigegeben: '' svn: URL 'svn: //gcc.gnu.org/svn/gcc/tags/gcc_5_2_1_release' existiert nicht'' –

Antwort

2

Der Konsens hier und anderswo scheint zu sein, dass GCC etwas Unerwartetes mit der Const und der Typedef tut. Ich weiß, dass Unerwartetes notwendigerweise mit einem Fehler gleichzusetzen ist, aber das ist für die GCC-Entwickler zu bestimmen.

Ich habe mein Kompilierungsproblem gelöst, indem ich ein Makro für den Funktionsaufruf definiert habe, das die nicht passende Typumwandlung in der Bibliothek behebt. Im Allgemeinen mag ich es nicht, an Bibliothekseinbauten zu basteln, aber das Makro erlaubt mir, den eigentlichen Bibliothekskopf nicht zu berühren und in meinem eigenen Code zu definieren, wo er für die Zukunft kommentiert werden kann, und die Testabdeckung dieses Codes sollte ein vernünftiges Frühwarnsignal sein Die zugrunde liegende Bibliothek ändert sich so, dass das Makro etwas kaputt macht.

Dies ist nicht so sehr "gelöst" wie "umgangen", aber jede weitere Einsicht wird wahrscheinlich von den GCC-Entwicklern kommen müssen.

+0

Ich würde gerne diesen Makro-Ausschnitt sehen – hewi

1

Wenn Sie cast 'a' als ConstSpiceDouble eingeben, führt GCC etwas Unerwartetes mit const und typedef aus, wodurch der Typ schließlich 'const const double' wird. Dies können Sie in der Fehlermeldung "const ConstSpiceDouble" sehen, was "const const double" entspricht, das funktioniert nicht.

Lösung ist entweder zu sagen 'a' const double oder zu sagen: 'a' ConstSpiceDouble ist, bevor Sie Parameter 'a' auf die foo Funktion

typedef const double ConstSpiceDouble; 
void foo(const double (*)[3]); 

int main(int argc, char **argv) { 

    const double a[3][3] = {{1,2,3},{1,2,3},{1,2,3}}; 
    // or ConstSpiceDouble a[3][3] = {{1,2,3},{1,2,3},{1,2,3}}; 

    foo(a); 

    return 0; 
} 

Die 'const' scheint vor anhängige ein neues Feature in den neuesten Versionen von gcc, aber davon bin ich mir nicht sicher :(

+0

Leider kann 'a' im eigentlichen Code nicht selbst const sein, da es modifiziert wird, da die Matrix vorher eingerichtet wurde zum Funktionsaufruf Ich habe gerade die minimale Menge an Code, die den Fehler zur Verdeutlichung reproduziert – Gravatite

+2

Der erste Absatz dieser Antwort ist falsch.Es gibt keine "automatische vor-ausstehende" in C. Der vorgeschlagene alternative Code kompiliert es jedoch hilft nicht, weil OP das Array in 'main' benötigt, um nicht-const zu sein –

+0

habe den" automatischen vorbereitenden "Teil entfernt – hewi

Verwandte Themen