3

I have a void* I am getting in some function which is actually a two-dimensional int array. I want to send it as an argument to a function that expects a two dimensional array. What is the BEST way to cast it properly?

void foo(void* val){
   //How to cast val in order to send to bar??
   bar()
}

void bar(int val[2][2]){
//Do something 
}
6
  • Doesn't void * translate itself automatically in C? Commented Nov 27, 2011 at 19:46
  • I cannot change the signature of bar! Commented Nov 27, 2011 at 20:17
  • @CarlNorum - just calling bar(val) will not compile Commented Nov 27, 2011 at 20:18
  • 1
    @Zahy: Have you tried it? It works in my compiler (GCC 4.6.1, C99 standard), and gives no warning even with all warnings turned on. Per the standard, I believe it should work in any C compiler (though not in a C++ compiler). Commented Nov 27, 2011 at 20:28
  • Yes. My mistake it does work(!) - responded too quickly. Commented Nov 27, 2011 at 20:50

1 Answer 1

7
bar((int(*)[2]) val);

(As Carl Norum states, the cast isn't even actually required; but it has the advantage of giving you a compiler warning if you accidentally pass it to a function expecting, say, a int(*)[3].)

Sign up to request clarification or add additional context in comments.

12 Comments

+1. It has the disadvantage of looking scary when it's really not. Judgement call on the programmer's part, I guess, but I'd try to avoid writing something so crazy looking if possible.
@CarlNorum: I know what you mean. Personally, I try to avoid having multidimensional arrays end up as void *, when I can, since the round-trip is particularly error-prone. One alternative to using a multidimensional array is to wrap up the int[2] into a struct. Another is to use a jagged array, though obviously that means having to deal with memory allocation.
@CarlNorum and ruakh, thanks. Array casting is possible then, But why this does not work:? int int2Arr[2][2] = (int(*)[2])theVoidPtr;
@Zahy: For the same reason that int arr1[2][2]; int arr2[2][2] = arr1; doesn't work. When an array is a parameter to a function, it's essentially just set up as a pointer to whatever is passed in; but when you declare an array as a local variable inside a function, the space for it is allocated on the stack, so it's not just a matter of reinterpreting an existing pointer.
@Zahy: If p is a void * that you know points to an int[...][2], you can write int (*arr)[2] = p; to declare an arr that has the same underlying data, but has type int[...][2]. You can then refer to arr[0][0], arr[0][1], arr[1][0], and arr[1][1], just as you'd expect. You cannot cast it to an int**, because in C, a multidimensional array is not an array of pointers. Internally it's basically stored as a one-dimensional array, and the compiler does all the work to treat arr[i][j] as ((int *)p)[2*i+j] (2 being the number of elements per row).
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.