1

Can I cast an an array of arrays int arr[4][10] to an array of pointers int *arr[4]?

How should I write the cast?

Xyand
  • 4,470
  • 4
  • 36
  • 63

2 Answers2

2

Can I cast an an array of arrays int arr[4][10] to an array of pointers int *arr[4]?

No.

You can cast int arr[4][10] to int (*arr)[10] though — or rather the former is implicitly convertible to the latter that you don't require any explicit cast at all.

BTW, it is better if you avoid using raw arrays to begin with. Prefer std::array<T,N> instead.

In this case, you could use std::array<std::array<int,10>,4>.. and then try designing your code in such a way which doesn't require casting at all.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • I'm actually integrating with some low level library code. So just to make it clear, I can only cast `arr` to a pointer to an array of size 10 (basically `&arr[0]`). Is that right? – Xyand Jul 23 '14 at 06:32
  • @Xyand: Yes, that is right :-). Since type of `arr[i]` is `int[10]`, `&arr[i]` is `int(*)[10]`, **not** `int*[10]` or `int*[4]` – Nawaz Jul 23 '14 at 06:33
  • @Xyand for your info, `arr` as an expression value is *already* an `int (*)[10]`. The syntax `&arr[0]` is not needed, nor is it needed for any of the other indices, which can be obtained with simply `arr + n`, each of them `int (*)[10]` – WhozCraig Jul 23 '14 at 06:37
  • Ok, let me try again. If the type of `arr[i]` is `int[10]` (which by itself can be cast to `int *`) and the same for `arr[i+k]` k=0..4. Then although we have an array of types that can be cast to `int *` we can't do the cast because then we lose the size of `int[10]` making `arrCast+1` meaningless. – Xyand Jul 23 '14 at 06:52
  • @WhozCraig: *`arr` as an expression value is already an `int (*)[10]`*. Wrong. `arr` is still `int[4][10]`. Just the name doesn't decay; it decays in a context **only if** the context requires it. – Nawaz Jul 23 '14 at 07:40
  • @Nawaz Um. the "as an expression value" is key to that comment, The "value" of said expression per the standard is the address of its first element, and the type pinned to that address is a pointer to said same. I never said the *type* of `arr` is `int(*)[10]` . Or is C++11 § 4.2,p1 suspended, and if so, *why* ? – WhozCraig Jul 23 '14 at 07:45
  • @WhozCraig `arr` as an expression value is _not_ `int (*)[10]`; it is `int [4][10]`. It will convert to `int (*)[10]` in many (but not all) contexts, but the expression `arr` itself has an array type, which can easily be shown (e.g. operand of `sizeof`, binding to a reference, etc.) – James Kanze Jul 23 '14 at 08:02
  • @WhozCraig "As an expression value" doesn't change the type. It's only when the implicit conversion occurs that you get a pointer (and even that doesn't change the type---it creates a new temporary object with the new type). – James Kanze Jul 23 '14 at 08:04
  • @JamesKanze I can certainly concur with that. My comment was specifically directed in regard to the opening full-sentence in this answer, which I thought odd only because no cast is actually required. Hind sight should have dictated better clarification on my part, as it would have likely avoided all of this (not that I don't revel in the opportunity of 240K combined-rep to respectfully share their knowledge). – WhozCraig Jul 23 '14 at 08:09
  • @WhozCraig: No. The *"as an expression value"* is **not** the key. Rather the *"context of the usage"* is the key. `func(arr);` does NOT necessarily pass pointer, it could pass the reference to the array (assume `func` takes a reference to an array) which doesn't require decay of the array. – Nawaz Jul 23 '14 at 08:51
  • 2
    Just a nit, but you _can_ cast an `int[4][10]` to `int *[4]`; a `reinterpret_cast` will do that nicely. You can't do anything with the results of the cast except to cast it back, of course---it doesn't miraculously change the layout of what is pointed to in memory. But the cast itself is legal and well defined. – James Kanze Jul 23 '14 at 08:56
  • @JamesKanze: That's correct, but I presumed the OP didn't mean that kind of cast because, as you said yourself, *"You **can't do** anything with the results of the cast **except** to cast it back, of course"*. – Nawaz Jul 23 '14 at 08:58
  • @Nawaz Yes, and that's why I categorized my comment as just a nit:-). The cast may be legal, but it doesn't advance anything to consider it. (Maybe we should categorize it as legal but immoral:-).) – James Kanze Jul 23 '14 at 09:10
  • @JamesKanze: Interesting phrasing "legal but immoral". I've never used `reinterpret_cast` in any meaningful way until very recently : https://github.com/snawaz/cson/blob/master/include/cson/cson.h%2B%2B – Nawaz Jul 23 '14 at 09:16
  • 1
    @Nawaz I've used it a couple of times, always in machine dependent code. Implementing a stack walk back, for example (which obviously depends on the compiler and the machine architecture). – James Kanze Jul 23 '14 at 10:15
2

note that "int* a[4]" has only 4 pointer to int,Otherwise it can indicate 4 int array,but int "a[4][10]" has 40 integer data type.
so you can not cast it.