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).
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.