0

How to use sizeof() to determine the size of a reference to an array?

I have declared an array in main() and used sizeof() to print its total size it has occupied.

And then I pass the array to a function as a reference to the array, but I am unable to use sizeof() for the reference (array) variable.

#include <iostream>

double sum(double (&list)[], size_t size);

int main(){
    double arr[]{34.5, 67.8, 92.345, 8.1234, 12.314, 3.4};
    double result{};

    std::cout << "size of the array : " << sizeof(arr) << std::endl;
    result = sum(arr, std::size(arr));
    std::cout << "the total is " << result << std::endl;
    
    return 0;
}

double sum(double (&list)[], size_t size){
    double total{};
    std::cout << "the size is : " << sizeof(list) << std::endl;

    for( int i{} ; i < size ; i++){
        total += list[i];
    }
    
    return total;
}

sizeof(list) shows a compiler error:

error: invalid application of ‘sizeof’ to incomplete type ‘double []’
     std::cout << "the size is : " << sizeof(list) << std::endl;

After changing the function parameter as double (&list)[6] I get the output I want, but why is sizeof(list) not working like sizeof(arr) when list is declared without explicitly mentioning its size in the declaration, though it's a reference?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 3
    *how to use sizeof() to determine the size of a reference to an array.* You don't. That's not what `sizeof` is for. You'll need to pass the size of the array as a parameter. Or use `std::array`. Or use `std::vector`. Or use the template technique for references to arrays. Or use the C++ idiomatic begin and end as iterator parameters to the function, from which you can calculate the size. – Eljay Aug 19 '23 at 14:45
  • 3
    The proper C++ answer is _don't use C style arrays_. Use `std::array`, `std::vector`, `std::span`, or iterators as applicable. Do note that that use of `sizeof` isn't the only problem with this code. Ever if you "fix" it, you'd still get a "no known conversion from 'double[6]' to 'double (&)[]'" error – Brian61354270 Aug 19 '23 at 14:46
  • re: _"but why sizeof(list) is not working like sizeof(arr)"_, see [Finding length of array inside a function](https://stackoverflow.com/q/17590226/11082165) and [How do I find the length of an array?](https://stackoverflow.com/q/4108313/11082165) and [When a function has a specific-size array parameter, why is it replaced with a pointer?](https://stackoverflow.com/q/1328223/11082165) – Brian61354270 Aug 19 '23 at 14:49
  • 1
    In `main`, print out the value of `std::size(arr), and compare it with `sizeof(arr)`. They do two different things. – Pete Becker Aug 19 '23 at 14:56
  • 1
    You can't create a reference to an array of unknown size. If you want the function to accept an array of any size, you need to use a template (`template double sum(double (&list)[N]);`) or a pointer (`double sum(double *list, size_t size);`) instead of a reference. – Remy Lebeau Aug 19 '23 at 14:57
  • TLDR not, stop using "C" style arrays and just use `std::vector` – Pepijn Kramer Aug 19 '23 at 16:03

2 Answers2

2

The size of a C-style array is part of its type, so an array declared as double arr[6]; has type (double)[6]. which is a complete type.

The sizeof operator works at compile-time. When you use sizeof on an array, it returns the size of the array in bytes. This is possible because the size of the array is part of its type and the compiler knows it at compile time.

However, if you attempt to use sizeof on an incomplete type such as (double)[], this will result in compilation error, as the type of the argument to sizeof has to be complete.

machine_1
  • 4,266
  • 2
  • 21
  • 42
1

Using C++ I would expect code like this without any sizeof :

#include <iostream>
#include <numeric>
#include <vector>

double sum(const std::vector<double>& values)
{
    double sum{ 0.0 };

    // IF you want to write loops, prefer using range based for loops (they will 'know' the size of values)
    for (const auto value : values)
    {
        sum += value;
    }

    return sum;
}

int main() 
{
    std::vector<double> values{ 34.5, 67.8, 92.345, 8.1234, 12.314, 3.4 };
    double result = sum(values);

    // no need to use sizeof in current C++, just ask the vector
    std::cout << "size of the array : " << values.size() << "\n";
    std::cout << "the total is " << result << "\n";

    // or to write code with no loops (in your code) at all
    std::cout << "the total using accumulate is " << std::accumulate(values.begin(), values.end(), 0.0);

    return 0;
}
Pepijn Kramer
  • 9,356
  • 2
  • 8
  • 19