Constant Matrix Transfer

Referring to this question and especially the accepted answer on the sheet, I wonder why gcc complains 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 destroy const , the compiler will still remain. Am I misunderstood something? I wanted to make sure func does not 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, such code is not very C-style, more like C ++. In C ++, there really would be no problem if I defined Array as a class containing all the matrix behavior.

 class Array {...}; 

I suppose I did not understand the concept of arrays and arrays of arrays in C very well and passed them to functions. Any enlightenment?

Thanks in advance.

EDIT2: Meanwhile, I chewed this problem a bit and seemed to converge on the following question: C / C ++ implicitly converts a pointer to int into a pointer to 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 ++ implicitly converts an array pointer from n int to an array pointer from n const int s. Despite the fact that the array n int implicitly converted to an array of n const int s. This level of indirection in implicit conversion is not 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; } 

This seems like a problem that C ++ does not implicitly convert a template for type A to a template of type B, even if A can be implicitly converted to B. Both templates have completely different types.

Correct answer?

+4
source share
2 answers

Your i variable is an array with 3 elements.

When you pass it to a function, inside the function it becomes a pointer to the first element. The compiler can add const either to the pointer or to what it points to: an array of 3 integers . However, it cannot change what an array of 3 integers points to an array of 3 constants .

I think you need to make a throw.

 #include <stdio.h> typedef const int array_of_3_constants[3]; void func(int (* const i)[3]) { ++i[0][0]; printf("Value: %d\n", i[1][1]); } void gunc(array_of_3_constants *i) { ++i[0][0]; /* error */ printf("Value: %d\n", i[1][1]); } int main(void) { int i[3][3] = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}}; func(i); func((array_of_3_constants*)i); /* warning */ gunc(i); /* warning */ gunc((array_of_3_constants*)i); return 0; } 
+2
source

You do not need to exclude const, just pass a compatible value by discarding the argument in the func function call:

  func ((void *) i);

If possible, it would be advisable to declare me as const, but this hack should work.

+1
source

All Articles