2015-02-24 3 views
14

Ich habe eine Funktion ein statisches zweidimensionales Array zu nehmen und die Elemente der Elemente des Arrays Behandlung als konstant:Unverträgliche Zeigertypen und Konstantheit

void test_function(const char arr[3][3]); 

Ich versuche, eine solche Funktion zu nennen, wie folgt :

char my_var[3][3] = { {0, 0, 0}, {0, 0, 0}, {0, 0, 0} }; 
test_function(my_var); 

Wenn mit gcc (ohne Flagge) kompilieren, erhalte ich die folgende Warnung:

test.c:9:8: warning: passing argument 1 of 'test_function' from incompatible pointer type 
    test_function(my_var); 
       ^
test.c:4:6: note: expected 'const char (*)[3]' but argument is of type 'char (*)[3]' 
void test_function(const char arr[3][3]); 

Wenn ich den const von Prototyp entfernen, wird die Warnung weg. Aber es ist nicht das, was ich will.

Beim Kompilieren mit clang mit beiden -pedantic-errors und -Wall bekomme ich keine Warnung über Zeiger Inkompatibilität.

Ich möchte nur verstehen, warum gcc in diesem Fall eine solche Warnung ausgibt. Warum sollten meine Zeiger/Arrays nicht kompatibel sein?

+0

Ich möchte sagen, das ist ein GCC-Bug - die Tatsache, dass Clang überhaupt keine Diagnose erzeugt, macht mich ziemlich misstrauisch. Übrigens sollten Sie beachten, dass es sich tatsächlich um eine Warnung und nicht um einen Fehler handelt (Sie scheinen sich mit '-Werror' kompiliert zu haben). – nneonneo

Antwort

10

GCC ist direkt auf das Schreiben des Standards und Clang ist falsch.

6.3.2.3/2:

Für jede Qualifier q, ein Zeiger auf einen Nicht-Q-qualifizierte Typ kann in einen Zeiger auf die q, Qualifizierte Version des Typs umgewandelt werden, ;

Sieht sehr vielversprechend aus. Aber halt dich fest.

6.2.5/26:

ein abgeleiteten Typ nicht von der Qualifikation (falls vorhanden) der Art, von der sie abgeleitet ist

Diese Bestimmung des Standard qualifiziert ist als angewandt speziell für Arrays ist nicht notwendig, und könnte leicht umgekehrt werden. Das heißt, const char[3] könnte leicht eine const-qualifizierte Version von char[3] gemacht werden. Aber es ist nicht. Sie sind nur verschiedene, inkompatible Typen. Tatsächlich gibt es in C überhaupt keine Const-qualifizierten Array-Typen, so dass Sie keine Const-qualifizierte Version von char[3] haben können. Das ist der Standard, mit dem wir leben müssen und müssen.

+1

Warum gibt gcc bei einer Funktion, die 'const char [3]' als Parameter verwendet und eine Variable vom Typ 'char [3]' übergibt, keine Warnung aus? –

+4

Weil 'const char [3]' als Funktionsparameter eine Lüge ist. Es wird stillschweigend als "const char *" behandelt. Das eigentliche Argument wird zu einem 'char *' zerfallen. Dann ist das ganze Geschäft von 6.3.2.3/2 abgedeckt, was ich zitiert habe. –

5

Aus den C-FAQ [Question 11.10]

In C, wenn man sich andere Hinweise, die Qualifier Mismatches haben als die erste Dereferenzierungsebene zuweisen oder übergeben müssen Sie explizite Casts verwenden müssen (zB (const char **) in diesem Fall), obwohl als immer, die Notwendigkeit für eine solche Besetzung kann ein tieferes Problem, das die Besetzung nicht wirklich beheben.

In Ihrem Fall:

test_function((const char (*)[3])my_var); 
Verwandte Themen