Zuweisung <Zeiger auf Array von Konstanten> = <Zeiger auf Array>: inkompatible Zeiger

Wenn ich so etwas kompiliere

double da[ 3 ] = { 2., 3., 4. };
double (* pda)[ 3 ] = &da;
double const (* cpda)[ 3 ] = pda; // gcc: warning; MSVC: ok

gcc warnt mich

warning: initialization from incompatible pointer type [enabled by default]

Frage: Was ist das Problem bei dieser Aufgabe? Ja, technisch gesehen handelt es sich um verschiedene Typen, aber ich sehe hier keine Gefahr.double const (*)[ 3 ] sieht für mich noch sicherer aus alsdouble (*)[ 3 ].

Ich habe einige Tests gemacht und die Ergebnisse verwirren mich noch mehr:

1) MSVC ist sehr zufrieden mitdouble const (* cpda)[ 3 ] = pda; Zuordnung, keine Fehler, keine Warnungen.

2) Sowohl gcc als auch MSVC sind damit zufrieden

double d = 1.;
double * pd = &d;
double const * cpd = pd;  // gcc: ok; MSVC: ok

während dies auch verschiedene Arten sind.

3) In diesem Beispiel

double d = 1.;
double * pd = &d;
double * * ppd = &pd;
double const * * cppd = ppd;  // gcc: warning; MSVC: error

gcc gibt dieselbe Warnung aus, aber MSVC gibt einen Fehler (!) aus.

Wer ist hier richtig? gcc oder MSVC?

Testergebnisse.

Compiler:

1) gcc version 4.7.2:http://www.compileonline.com/compile_c_online.php

2) MSVC-Version (als C ++ - Code) 'VS2012CTP' 17.00.51025 für x86:http://rise4fun.com/vcpp

3) MSVC (als C-Code) VS2010: offline getestet

int main()
{
    double d = 1.;

    double * pd = &d;
    double const * cpd = pd;
    // gcc: ok
    // MSVC C++: ok
    // MSVC C: ok

    double * * ppd = &pd;
    double const * * cppd = ppd;
    // gcc: warning: initialization from incompatible pointer type [enabled by default]
    // MSVC C++: error C2440: 'initializing' : cannot convert from 'double **' to 'const double **'
    // MSVC C: ok

    double da[ 3 ] = { 2., 3., 4. };

    double (* pda)[ 3 ] = &da;
    double const (* cpda)[ 3 ] = pda;
    // gcc: warning: initialization from incompatible pointer type [enabled by default]
    // MSVC C++: ok
    // MSVC C: ok

    cpd, cpda;
    return 0;
}

Bearbeiten:

Ich habe dies gerade auf meinem Visual Studio als C-Code kompiliert (nicht C ++) und es gibt keine Fehler, überhaupt keine Warnungen. Ich habe Kommentare zum obigen Code bearbeitet

Antworten auf die Frage(3)

Ihre Antwort auf die Frage