tags:

views:

147

answers:

6
+11  A: 

When declaring a function parameter, the following two are equivalent because an array decays to a pointer when it is passed as an argument:

int array[]
int *array;

So, you end up computing sizeof(int*) / sizeof(int), which happens to be one on your platform because their sizes are the same.

If you need the size of the array in your function, you should pass it as an argument to the function, or use a container that keeps track of the size for you.

James McNellis
The thing is, in other cases, sizeof(array) / sizeof(int) actually DOES return size of array. Only in my (fairly crazy, I suppose) example, it doesn't.
Karel Bílek
James McNellis
OK, that is probably the thing that got me confused... that sometimes, sizeof treats it "specially" as an array, but sometimes just as an ordinary pointer. Thanks
Karel Bílek
the point is - there is no runtime info attached to an array saying how big its is, and anyway sizeof is resolved at compile time. THis should tell you that it will fail. You can call static_class() with any sized array; the compiler cannot possibly know; all the compiler sees is that there will be a pointer to the start of an array of ints passed in
pm100
@Karel: Really, `sizeof` doesn't treat anything specially. When you have the array, it gives you the size of the array; when you only have a pointer to the first element of the array, it gives you the size of that first element. Basically, you just have to remember that when the array gets converted to a pointer to its first element, you lose all information about the size of the array, because all you have is a pointer.
James McNellis
and btw - use std:vector - its what you want
pm100
James: well, I didn't know that sizeof is computed at compile time. It makes much more sense now.
Karel Bílek
pm100: can I use something like that easy braces initialization on vector?
Karel Bílek
@Karel: It's the same reason you can't just pass an array to any old function, you also need to pass its size.
rlbond
A: 

becuase array is a pointer at the point where you do sizeof(array). The array never knew its size (see what happens if you try to access an element beyond its end). The compiler knew at the point where it was defined; that all

Anyway the solution you want is std::vector

pm100
+1  A: 

In C, and therefore I presume in C++, any array that's passed through as a parameter is turned into a simple pointer type, which loses the size information. Since your static_class constructor gets the array from a parameter, it loses its array quality.

Kyte
A: 

You'd be surprised, but in C++, arrays are just pointers, nothing more. The array size is not stored anywhere, and certainly it not possible to pass function arguments of variable size.

Fyodor Soikin
Arrays are not pointers. This myth has been debunked too many times to do it here again. It is described in good detail in any C/C++ FAQ.
AndreyT
Yes, you're right. I stand corrected.
Fyodor Soikin
+3  A: 

There's also a template option, something like this?

class static_class
{
public:
   template<int I>
   static_class(int (&array)[I])
   {
      std::cout << I << std::endl;
   } 
};

I think that'd work, anyway. sizeof(array)/sizeof(array[0]) only works in scopes where the array's definition is actually visible. In other words, your static_class constructor couldn't "see" the size of the array, all it knew was that it was getting an array of some (any) size. You could pass an array of 100 elements or four, and the function itself would get no information.

In my example, on the other hand, the template will cause one version of the function to be created for each array size that you pass in. This may or may not be desirable. Generally speaking, it's best to keep the array size somewhere handy, like:

class my_class
{
public:
   static static_class s;
   static const int array_size = 4;
   static int array[array_size];
};

Then you can pass my_class::array_size around and not have to be worried about what the compiler may or may not have visible regarding array attributes.

dash-tom-bang
A: 

The basic problem that the other answers hint at is that arrays are not first class types in C/C++. In particular, you cannot declare functions or function types that take arrays as arguments. Now, for historical reasons lost in the depth of time, instead of just saying that declaring a function argument that is an array is an error, it was decided that the compiler should silently turn the array declaration into a pointer declaration. This has lead to no end of confusion with people declaring arrays as arguments and unexpectedly getting pointers instead.

Chris Dodd