Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent pointer from being passed as array

So while it is common/typical to accept an array that has decayed to a pointer like the following

#include <iostream>

void example(int* data)
{
    std::cout << data[0] << ' ' << data[1] << ' ' << data[2] << std::endl;
}

int main()
{
    int data[3] = {1, 2, 3};
    example(data);
}

I noticed that you can also seemingly do the opposite. Namely you can pass a pointer that will undecay(?) back to an array

#include <iostream>

void example(int data[3])
{
    std::cout << data[0] << ' ' << data[1] << ' ' << data[2] << std::endl;
}

int main()
{
    int data[3] = {1, 2, 3};
    example(data);
    example(nullptr);  // Is this legal? Can I prevent this?
}

Note that the data argument of example has changed from int* to int[3] yet I am still able to pass nullptr. Changing the argument to std::array<int, 3> will obviously prevent this, but I'm curious if this implicit conversion is described by the standard? There is a lot of commentary on "array to pointer" implicit conversion, but this seems to be the other way around.

like image 843
Cory Kramer Avatar asked Aug 11 '21 16:08

Cory Kramer


2 Answers

In fact,

void example(int data[3])

is

void example(int data[])

or

void example(int* data)

You need

void example(/*const*/ int (&data)[3])

to have array reference, (and so rejecting pointer or array of different size).

like image 113
Jarod42 Avatar answered Sep 24 '22 19:09

Jarod42


When you have

void example(int data[3])

that array itself decays to a pointer so the function is actually

void example(int* data)

which is why you can still pass nullptr to the function. The relevant paragraph for this is [dcl.fct]/5

The type of a function is determined using the following rules. The type of each parameter (including function parameter packs) is determined from its own parameter-declaration ([dcl.decl]). After determining the type of each parameter, any parameter of type “array of T” or of function type T is adjusted to be “pointer to T”. [...]

emphasis mine

like image 20
NathanOliver Avatar answered Sep 24 '22 19:09

NathanOliver