2015-12-28 18 views
17

Erwägen Programm folgend:Zeiger auf Array mit konst Qualifier in C & C++

int main() 
{ 
    int array[9]; 
    const int (*p2)[9] = &array; 
} 

Es kompiliert fein in C++ (siehe Live-Demo here), aber nicht in Kompilierung in C standardmäßig GCC gibt folgende Warnungen. (Siehe Live-Demo here).

prog.c: In function 'main': 
prog.c:4:26: warning: initialization from incompatible pointer type [enabled by default] 
    const int (*p2)[9] = &array; 

Aber Wenn ich -pedantic-errors Option:

gcc -Os -s -Wall -std=c11 -pedantic-errors -o constptr constptr.c 

es mir Fehler folgende Compiler

constptr.c:4:26: error: pointers to arrays with different qualifiers are incompatible in ISO C [-Wpedantic] 

Warum es nicht in Kompilierung in C, aber nicht in C++ gibt? Was sagt C & C++ Standard darüber?

Wenn ich const Qualifier in Array-Deklaration Anweisung verwenden kompiliert es auch in C gut. Also, was passiert hier im obigen Programm?

+10

Während ich verstehe, ist dies eine gute Frage, aber einfach zu fragen, was C & C++ Standard darüber sagt? 'Ist nicht gut. Hast du versucht, in die Standards zu schauen? Welchen Teil hast du nicht verstanden? Haben Sie Unterschiede festgestellt? Wo sind Ihre Forschungsanstrengungen? Hoffe ich werde verstanden. :) –

Antwort

20

GCC-gnu

In GNU C, Zeiger mit Qualifier auf Arrays arbeiten, um Verweise auf andere qualifizierte Typen ähnlich. Zum Beispiel kann ein Wert vom Typ int (*)[5] verwendet werden, um eine Variable vom Typ const int (*)[5] zu initialisieren. Diese Typen sind in ISO C nicht kompatibel, da das const Qualifikationsmerkmal formal dem Elementtyp des Arrays und nicht dem Array selbst zugeordnet ist.

C Standard sagt, dass (Abschnitt: §6.7.3/9):

Wenn die Spezifikation eines Arrays Typ Jede Art Qualifizierer umfasst, der Elementtyp sogenannten qualifiziert ist, nicht der . Array-Typ [...]

Nun ein Blick auf den C++ Standard (Abschnitt § 3.9.3/5):

[...] Cv-Qualifizierer, die auf einen Array-Typ angewendet werden, werden an den zugrunde liegenden Elementtyp angehängt. Daher bezieht sich die Notation "cv T", wobei T ein Array-Typ ist, auf ein Array, dessen Elemente so qualifiziert sind. Ein Array-Typ, dessen Elemente cv-qualifiziert sind, hat auch die gleichen cv-Qualifikationen wie seine Elemente. [Beispiel:

typedef char CA[5]; 
typedef const char CC; 
CC arr1[5] = { 0 }; 
const CA arr2 = { 0 }; 

Die Art sowohl der arr1 und arr2 ist „Array von 5 const char“und die Array-Typ const qualifizierte angesehen wird.-endexample]

, deshalb ist die Initialisierung

const int (*p2)[9] = &array; 

ist Zuweisung von Typ Zeiger auf Array [9] von int zu Zeiger auf Array [9] von const int. Dies entspricht nicht der Zuweisung von int * an eine const int *, wobei const direkt auf den Objekttyp angewendet wird, auf den der Zeiger auf zeigt. Dies ist bei const int(*)[9] nicht der Fall, wobei in C const auf die Elemente des Array-Objekts anstelle des Objekts angewendet wird, auf das der Zeiger zeigt. Dies macht die obige Initialisierung inkompatibel.

Diese Regel wird in C++ geändert. Als const auf Array-Objekt angewendet wird selbst, ist die Zuordnung zwischen gleichen Arten Zeiger auf const array [9] von int anstelle von Typ Zeiger auf Array [9] von int und Zeiger auf Array [9] von const int.

+0

Gute Verbindung. Aber die Antwort sagt immer noch nicht, was der C++ - Standard dazu sagt? – Destructor

+4

Ich würde dies einen Fehler in ISO C nennen. Es macht keinen Sinn. Sie sollten immer in der Lage sein, einem Zeigerziel auf jeder Ebene "const" hinzuzufügen. –

+1

@PravasiMeet; Zitat vom C++ Standard hinzugefügt. – haccks