防止指针作为数组传递

Cor*_*mer 5 c++ arrays pointers language-lawyer

因此,虽然接受已经衰减为如下指针数组是常见/典型的

#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);
}
Run Code Online (Sandbox Code Playgroud)

我注意到你似乎也可以做相反的事情。也就是说,您可以将一个指针传递给数组,该指针将不衰减(?)

#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?
}
Run Code Online (Sandbox Code Playgroud)

请注意, 的data参数example已从 更改为int*int[3]但我仍然能够通过nullptr。将参数更改为std::array<int, 3>显然会阻止这种情况,但我很好奇标准是否描述了这种隐式转换?有很多关于“数组到指针”隐式转换的评论,但这似乎是相反的。

Jar*_*d42 10

实际上,

void example(int data[3])
Run Code Online (Sandbox Code Playgroud)

void example(int data[])
Run Code Online (Sandbox Code Playgroud)

或者

void example(int* data)
Run Code Online (Sandbox Code Playgroud)

你需要

void example(/*const*/ int (&data)[3])
Run Code Online (Sandbox Code Playgroud)

有数组引用,(因此拒绝不同大小的指针或数组)。


Nat*_*ica 5

当你有

void example(int data[3])
Run Code Online (Sandbox Code Playgroud)

该数组本身衰减为一个指针,因此该函数实际上是

void example(int* data)
Run Code Online (Sandbox Code Playgroud)

这就是为什么您仍然可以传递nullptr给函数的原因。相关段落是[dcl.fct]/5

使用以下规则确定函数的类型。每个参数的类型(包括函数参数包)由它自己的参数声明([dcl.decl])决定。在确定每个参数的类型后,任何类型为“数组 T”或函数类型为 T 的参数都被调整为“指向 T 的指针”。[...]

强调我的