1

I'm writing a simple C++ code to count the number of elements in an array. I use template so that I can deal with arrays of different type.

template <typename T>
void count(T a[]){

    cout << "size of array: " << sizeof(a) << endl;
    cout << "size of element: " << sizeof(*a) << endl;
    cout << "count number: " << sizeof(a)/sizeof(*a) << endl;
}

int main()
{
    int x[6] ={1,2,3,4};

    count(x);
    cout << sizeof(x) << endl;
    cout << sizeof(*x) << endl;
    cout << sizeof(x)/sizeof(*x) << endl;

    return 0;
}

But when I run this code, I got different results by using function count and by just copying the same code in main. I can't figure out why. The results are like this:

size of array: 8
size of element: 4
count number: 2
24
4
6

What's more, when I use g++ compiler to run the code, there is a warning message:

warning:sizeof on array function parameter 'a' will return size of int* [-Wsizeof-array-argument]
  cout << "size of array: " << sizeof(a) << endl;

This message did't show up when I use Code::Blocks running the code, but I think it might show my problem.

Where do these two different results come from?

CursorCC
  • 23
  • 5
  • Must be a duplicate on this somewhere, in short due to *pointer decay*. – Bathsheba Sep 16 '19 at 16:14
  • You're not passing an array, you're passing a *pointer*. And the size of a pointer is the size of the pointer itself, not what it might point to. As an argument, `T a[]` will be treated as `T* a`. – Some programmer dude Sep 16 '19 at 16:14
  • `sizeof(a)` is `sizeof(T*)` and not `sizeof(T[6])` – Jarod42 Sep 16 '19 at 16:14
  • 1
    Inside `main` `x[]` is an array. But when you pass it to the function it *decays* in a pointer. `sizeof` for arrays is not the same as for pointers. – Ripi2 Sep 16 '19 at 16:15
  • 3
    This is one of several reasons why you should ignore inbuilt arrays and use `std::vector` (or `std::array`). – Max Langhof Sep 16 '19 at 16:18
  • 1
    If you can (i.e. if it is allowed), I would suggest you use `std::array` instead of C style arrays. That way, you can pass it to a function and still call `a.size()` to get its size. For dynamically sized arrays, use `std::vector` – eike Sep 16 '19 at 16:19
  • @MaxLanghof Looks like I was a little late :D – eike Sep 16 '19 at 16:19
  • Code::Blocks is an IDE, not a compiler. so it depends of compiler (and flag/option) used inside Code::Blocks. – Jarod42 Sep 16 '19 at 16:20

2 Answers2

4

I cannot precisly predict how the compiler interprets your code, but What do you think is the T in your called template function? int? or int[]? or int[6]? or rather int[4] (the initialized size)?

You must define the complete array as the template type T, so the right declaration would be:

template <typename T>
void count(T a)

Also I recommend to replace sizeof(*a) with sizeof(a[0]) - it's the same, but expresses better what it means.

Btw. there a standard macro _countof, which gives you the number of elements of an array.

Nick
  • 472
  • 3
  • 18
2

It's because your template:

template <typename T>
void count(T a[])

decays to:

template <typename T>
void count(T a*)

so you're printing the sizeof a pointer, not of the array as your main is.

The error message says this:

will return size of int*

Paul Evans
  • 27,315
  • 3
  • 37
  • 54