When I compile something like this
double da[ 3 ] = { 2., 3., 4. };
double (* pda)[ 3 ] = &da;
double const (* cpda)[ 3 ] = pda; // gcc: warning; MSVC: ok
gcc warns me
warning: initialization from incompatible pointer type [enabled by default]
Question: What's the problem with this assignment? Yes, technically, these are different types, but I don't see any danger here, double const (*)[ 3 ]
looks even safer for me than double (*)[ 3 ]
.
I did some tests and results confuse me even more:
1) MSVC is quite happy with double const (* cpda)[ 3 ] = pda;
assignment, no errors, no warnings.
2) Both gcc and MSVC are happy with this
double d = 1.;
double * pd = &d;
double const * cpd = pd; // gcc: ok; MSVC: ok
while these are different types too.
3) In this example
double d = 1.;
double * pd = &d;
double * * ppd = &pd;
double const * * cppd = ppd; // gcc: warning; MSVC: error
gcc gives the same warning but MSVC gives error(!).
Who is right here? gcc or MSVC?
Test results.
Compilers:
1) gcc version 4.7.2: http://www.compileonline.com/compile_c_online.php
2) MSVC (as C++ code) version 'VS2012CTP' 17.00.51025 for x86: http://rise4fun.com/vcpp
3) MSVC (as C code) VS2010: tested offline
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;
}
Edit:
I just compiled this on my Visual Studio as C code (not C++) and it gives no errors, no warnings at all. I edited commentaries to above code
gcc
is right here and the diagnostic is required in C.
double da[ 3 ] = { 2., 3., 4. };
double (* pda)[ 3 ] = &da;
double const (* cpda)[ 3 ] = pda; // diagnostic here
Basically you are trying to assign an object of type T1
to an object of type T2
(constraints of simple assignment apply for initializations).
Where T1
is a pointer to an array N
of T
.
And T2
is a pointer to an array N
of const T
.
In the constraints of the simple assignment, C says that for pointers the following shall hold (in C99, 6.5.16.1p1):
both operands are pointers to qualified or unqualified versions of compatible types, and the type pointed to by the left has all the qualifiers of the type pointed to by the right
This would allow for example something like:
int a = 0;
const int *p = &a; // p type is a qualified version of &a type
But in your example, a pointer to an array N
of const T
is not a qualified version of a pointer to an array N
of T
. In C an array cannot be constant: there is not const
arrays, but only arrays of const
elements.