samedi 29 mai 2021

Getting the length of an array of undetermined size at compile time

I was just messing around with Compiler Explorer a bit... I was asking myself why there is no lenth() function in C++ to determine the size of an array at compile time, because in my opinion it should be easy to write. But apparently it's not that easy. My idea was something like this:

#include <iostream>

using namespace std;

void print_all(const int num[], const size_t n)
{
    for (size_t i = 0; i < n; ++i)
        cout << num[i] << endl;
}

template <class T, size_t N>
constexpr size_t  length(T (&arr)[N])
{
    return N;
}

int main()
{
    constexpr int a[] { 1, 2, 3, 4 };
    print_all(a, length(a));
}

However, according to godbolt.org with clang 11.0.1, x86-64, this will be compiled into the following:

main:                                   # @main
        ...
        call    unsigned long length<int const, 4ul>(int const (&) [4ul])
        mov     rdi, qword ptr [rbp - 24]       # 8-byte Reload
        mov     rsi, rax
        call    print_all(int const*, unsigned long)
        xor     eax, eax
        add     rsp, 32
        pop     rbp
        ret
unsigned long length<int const, 4ul>(int const (&) [4ul]):             # @unsigned long length<int const, 4ul>(int const (&) [4ul])
        push    rbp
        mov     rbp, rsp
        mov     qword ptr [rbp - 8], rdi
        mov     eax, 4
        pop     rbp
        ret

So it's not inlined.

Is there a way to get a convenience function with zero runtime cost?

PS: I am not interested in this because I actually want to use such a function. I know that std::array or std::span would be way better solutions in almost all cases and that the raw loop in print_all is fishy etc. I am asking this because I want to improve my understanding of C++ and because arrays of undetermined size occur 'in the wild.' Also I am aware that I could use sizeof(a)/sizeof(a[0]), but I was thinking that there should be a way to get things like this done using templates and constexpr because that's somehow what they are for (creating convenience that can be paid for at compile time).

Aucun commentaire:

Enregistrer un commentaire