5

I have the following code:

typedef float vec3_t[3];

void f(const vec3_t v[2]){
    // do stuff
}

int main(int argc, char * argv[]){
    vec3_t v[2];
    v[2][1] = 1;
    f(v);
    return 0;
}

which will not compile using

gcc main.c -std=gnu99 -O0 -o main

but give the error

main.c: In function ‘main’:'
main.c:293:5: warning: passing argument 1 of ‘f’ from incompatible pointer type [enabled by default]
     f(v);
     ^
main.c:286:6: note: expected ‘const float (*)[3]’ but argument is of type ‘float (*)[3]’
 void f(const vec3_t v[2]){
      ^

If I on the other hand remove the const requirement in the function f. It all works well. I can not figure out what is wrong??

Robert
  • 725
  • 1
  • 7
  • 15
  • See also: http://stackoverflow.com/questions/28062095/pass-a-two-dimensional-array-to-a-function-of-constant-parameter – Grzegorz Szpetkowski May 04 '16 at 14:00
  • As mentioned in my dupe link, this is probably a flaw in C type system. I think this highlights why hiding pointers or arrays behind `typedef` is not a good idea. – user694733 May 04 '16 at 14:01
  • It is not an exact duplicate, because the linked question was regarding array pointers. In this case there are 2D arrays. The answer will be pretty much the same though. – Lundin May 04 '16 at 14:30
  • Anyway, I would strongly recommend to not hide arrays behind typedefs. If you need a distinct type, put the array inside a struct. Then make an array of such structs. Coincidentally, that would have solved this problem too. – Lundin May 04 '16 at 14:36
  • @user694733: Ok, but actually this issue does not arise from the typedef. Type out the float[3] and you get the same compiler warning. – Robert May 04 '16 at 14:39

1 Answers1

0

Why not cast the parameter to const?

typedef float vec3_t[3];

void f(const vec3_t v[2]){
    // do stuff
}

int main(int argc, char * argv[]){
    vec3_t v[2];
    v[2][1] = 1;
    f((const vec3_t*)v);
    return 0;
}
Brian Zammit
  • 179
  • 6
  • 2
    Reaching for a cast is not a good idea. The compiler complains for a reason. Unless you know more than your compiler, simply casting is likely to lead to trouble, sooner or later. – Jonathan Leffler May 04 '16 at 14:07
  • Implementing a safe "const cast" through C11 `_Generic` was one possible solution discussed in the linked duplicate, see for example the answer by chux. If it is a good idea or not, I'm not sure. But it would be 100% safe, unlike the raw cast here. – Lundin May 04 '16 at 14:34