Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't std::extent work on references to arrays like operator sizeof?

Tags:

c++

arrays

extent

If I want to get the size (number of elements) of an array I can use sizeof(a) / sizeof(a[0]) but the new standard makes it possible to use type traits to do that:

int main(){

    int a[]{5, 7, 2, 3, 6, 7};

    std::cout << std::extent<decltype(a)>::value << '\n'; // 6

    auto& refA = a;
    std::cout << std::extent<decltype(refA)>::value << '\n'; // 0
    std::cout << sizeof(refA) / sizeof(refA[0]) << '\n'; // 6
    std::cout << std::extent<std::remove_reference<decltype(refA)>::type>::value << '\n'; // 6
 
    std::cout << "\ndone!\n";
}

Everything is OK but why doesn't std::extent work on references to arrays as the sizeof() operator does? I've had to remove the reference in the last example to get the actual array type.

like image 231
Maestro Avatar asked Jan 16 '21 21:01

Maestro


People also ask

Why doesn't sizeof (A)/sizeof (A[0]) work when applied for an array passed as parameters?

Originally Answered: Why doesn't sizeof (a)/sizeof (a [0]) doesn't work when applied for an array passed as parameters? The behavior you found is actually a big wart in the C language. Whenever you declare a function that takes an array parameter, the C standard requires the compiler to ignore you and change the parameter to a pointer.

How does a function know the size of an array?

Arrays in C do not know their size. When you pass them to a function as an argument, you are passing a pointer. All information about their size is lost at that time. The receiving routine knows nothing about the array's size.

Why can't I see the size of an array in C?

Because there really are not arrays in C, just anonymous stretches of memory with a base address. When you pass an "array" in C, the compiler passes the base address of the array AND NOTHING MORE. So the receiving function has no way of knowing the exact type, dimensions, or size of the array.

Why does @sizeof (A) fail to compile?

ARRAY_SIZE will fail to compile if compiler has silently converted the argument to a pointer. Because `sizeof (a)` is referring to `a` as a pointer rather than an array. In C an array's length must be passed separately because it is not remembered within the array.


1 Answers

This doesn't answer the question as written directly, but rather a potential xy problem. You shouldn't nor do you need to use std::extent to do this. It's not useful in this case. Use std::size instead:

std::size(a)

Now for the answer:

why doesn't std::extent work on references to arrays

It works; just not in the way you may have been expecting. In particular, the extent of any reference is 0 rather than the extent of the referred type.

like image 93
eerorika Avatar answered Oct 16 '22 15:10

eerorika