Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Runtime sized arrays and pointer-decay

I was testing some of the tools in the type_traits header over the new C++14 runtime sized arrays, consider the code below:

int g[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};

template <typename T> void print(T &t)
{
    std::cout << "Type id:    " << typeid(T).name() << '\n';
    std::cout << "is_array:   " << std::is_array<decltype(T)>::value << '\n';
    std::cout << "is_pointer: " << std::is_pointer<decltype(T)>::value << '\n';
    std::cout << "extent:     " << std::extent<decltype(T)>::value << '\n';
}

int main()
{
    print(g);
    return 0;
}

The static sized array g returns the following output:

Type id:    A11_i
is_array:   1
is_pointer: 0
extent:     11

The unmangled name A11_i I'm assuming that is Array of 11 elements of type int so all is correct here, but with this new code:

void f(std::size_t s)
{
    int a[s];
    print(a);
}

int main()
{
    f(5);
    return 0;
}

I'm getting errors:

In function 'void f(std::size_t)':
error: no matching function for call to 'print(int [s])'

note: candidate is:
note: template<class T> void print(T&)
note:   template argument deduction/substitution failed:
note:   variable-sized array type 'int [s]' is not a valid template argument

I wasn't expecting that the size argument could be passed to the template but I was expecting an automatic array-to-pointer decay. I guess that the argument T & isn't suited for this kind of decay so I've tried to change the template signature to:

template <typename T> void print(T *&t)

With similar results:

In function 'void f(std::size_t)':
error: no matching function for call to 'print(int [s])'

note: candidate is:
note: template<class T> void print(T*&)
note:   template argument deduction/substitution failed:
note:   mismatched types 'T*' and 'int [s]'

And I've noticed that the size variable on the runtime sized array seems to be tied to the type (instead of mismatched types 'T*' and 'int [5]' we're getting mismatched types 'T*' and 'int [s]') this looks pretty weird.

So, what's the question?

  • Why I'm not getting an array-to-pointer decay in this runtime sized array?
  • Is the variable used to size the runtime sized array part of the type of the runtime sized array or I'm misunderstanding the error?
like image 664
PaperBirdMaster Avatar asked Apr 13 '15 10:04

PaperBirdMaster


People also ask

What does it mean to decay an array to a pointer?

The loss of type and dimensions of an array is known as decay of an array. This generally occurs when we pass the array into function by value or pointer.

Why do arrays decay?

The loss of type and dimensions of an array is known as array decay. It occurs when we pass the array into a function by pointer or value. First address is sent to the array which is a pointer. That is why, the size of array is not the original one.

What is decay in programming?

In software development, “code decay” refers to the increasing difficulty and intricacy of code modification.


1 Answers

During template argument deduction, the array-to-pointer conversion is only used if the function template parameter's type is not a reference.

§14.8.2.1 Deducing template arguments from a function call [temp.deduct.call]

1 Template argument deduction is done by comparing each function template parameter type (call it P) with the type of the corresponding argument of the call (call it A) as described below. [...]

2 If P is not a reference type:

  • If A is an array type, the pointer type produced by the array-to-pointer standard conversion (4.2) is used in place of A for type deduction; otherwise,
  • [...]
like image 93
T.C. Avatar answered Sep 29 '22 19:09

T.C.