2

I would like to have the following method as a generic method for any array,

int arrayLength(`anyType` array[])
{
    return sizeof(array) / sizeof(array[0]);
}

However it appears C++ doesn't allow any ambiguity of types at all,

why is this, and how should I go about getting around it?

khr055
  • 28,690
  • 16
  • 36
  • 48
Troyseph
  • 4,960
  • 3
  • 38
  • 61
  • 8
    `template std::size_t arrayLength(T (&)[N]) { return N; }` – ildjarn Jan 23 '12 at 21:25
  • Duplicate: http://stackoverflow.com/questions/4415524/common-array-length-macro-for-c – Seva Alekseyev Jan 23 '12 at 21:28
  • another related thread: http://stackoverflow.com/questions/95500/can-this-macro-be-converted-to-a-function – Troyseph Jan 23 '12 at 22:00
  • @ilgjarn Would it be possible for you to explain your code to me in full, i.e. spell it out like i'm a complete dummy, because I'd really like to understand everything that it is doing, Thanks – Troyseph Jan 23 '12 at 22:15
  • @Sebastian : It appears to me to be explained in detail in the very answer you linked to. – ildjarn Jan 23 '12 at 22:30
  • @ilgjarn I don't understand the (&)[N] part, I can't find an explanation for this anywhere – Troyseph Jan 23 '12 at 22:56
  • @Sebastian : `T (&)[N]` is an unnamed argument that is a reference to a `T[N]` (i.e., an array of `T` of length `N`). Name the argument if that makes it easier to understand, e.g. `T (&arr)[N]`. – ildjarn Jan 23 '12 at 22:59
  • @ilgjarn why is the named argument in brackets, and why is it simply referenced and not just passed in normally though? Thanks – Troyseph Jan 23 '12 at 23:16
  • @Sebastian : C-arrays cannot be passed by value without decaying into a pointer so the only way to deduce the C-array's size is to pass by reference. If one were using `std::array<>` or `boost::array<>` then this wouldn't be an issue (hint hint). – ildjarn Jan 23 '12 at 23:18
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/6980/discussion-between-sebastian-troy-and-ildjarn) – Troyseph Jan 23 '12 at 23:21

3 Answers3

3

Because types have to be pushed onto the stack and then popped back off, and the sizeof one type is not equal to the sizeof another type.

If the size of types being passed on the stack between functions is not fixed or known in advance, how can the compiler compile a function?

The solutions to this problem -- as others have noted -- is templates and macros, both of which dynamically generate code -- which is then, in turn, compiled -- at compile-time, appearing to "solve" the problem, but really only obviating or distracting you from it by offloading the work onto the compiler.

1

In Visual C++ there's a __countof() construct that does the same. It's implemented as a template for C++ compiling and as a macro for C. The C++ version errors out if used on a pointer (as opposed to a true array), the C version does not.

Seva Alekseyev
  • 59,826
  • 25
  • 160
  • 281
1

I think what you're really asking is "Why does C++ insist on static typing?"

The answer: because it's easier to write a compiler that generates small, fast programs if the language uses static typing. And that's the purpose of C++: creating small, fast programs whose complexity would be relatively unmanageable if written in C.

When I say "small", I'm including the size of any required runtime libraries.

egrunin
  • 24,650
  • 8
  • 50
  • 93