Referring to this question and especially the accepted answer of litb, I wonder why the gcc complain about this:
void func(const int (*ip)[3]) {
printf("Value: %d\n", ip[1][1]);
}
int main() {
int i[3][3] = { {0, 1, 2} , {3, 4, 5}, {6, 7, 8} };
func(i);
return 0;
}
If I eliminate the const
the compiler keeps still. Did I something misunderstand? I wanted to be sure that func
don't modify my array.
EDIT: The same thing happens if I define a data type for my matrix:
typedef int Array[3][3];
void func(const Array *p) {
printf("Value: %d\n", (*p)[1][1]);
}
int main() {
Array a = { {0, 1, 2}, {3, 4, 5}, {6, 7, 8} };
func(&a);
return 0;
}
I accept, this kind of code isn't very C style, more like C++. In C++ indeed there would be no problem if I define Array as a class containing all the matrix behavior.
class Array {...};
I suppose, I didn't understand very well the concept of arrays and arrays of arrays in C and passing them to functions. Any enlightenment?
Thank you in advance.
EDIT2: Meanwhile I chewed a bit on this problem and it seems to converge to the following question: C/C++ implicitly converts a pointer to an int
to a pointer to an const int
. Thus the following works:
func(const int a[]) // aquivalent: func(const int *a)
{ ... }
int main()
{
int b[10];
func(b);
return 0;
}
But C/C++ don't implicitly converts a pointer to an array of n int
s to a pointer to an array of n const int
s. Even though an array of n int
s is implicitly converted to an array of n const int
s. This level of indirection in the implicit conversion isn't supported. The following will be rejected (at least with a warning in C):
func(const int a[][n]) // aquivalent: func(const int (*a)[n])
{ ... }
int main()
{
int b[m][n];
func(b);
return 0;
}
It's similar to the problem that C++ doesn't implicitly convert a template for the type A into a template of type B even if A can be implicitly converted to B. The two templates are of completely different types.
Is this the right answer?