【问题标题】:Prevent pointer from being passed as array防止指针作为数组传递
【发布时间】:2021-10-15 03:00:30
【问题描述】:

因此,虽然接受 array that has decayed to a pointer 如下所示是常见/典型的

#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);
}

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

#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?
}

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

【问题讨论】:

  • 我不会称之为“普通/典型”。当然这要看你习惯用什么样的代码了
  • @463035818_is_not_a_number 我处理的代码范围从“昨天写的”到“20 年前写的”,所以我同意这在很大程度上取决于代码库,但总的来说是(或曾经是?)一个很常见的成语。
  • void example(int* data, int size) 会更常见,但无论如何它是类 C 代码,而不是真正的 C++。
  • 回复:example(nullptr);:“这合法吗?” - 是的。 “我可以阻止它” - 是的,通过添加已删除的重载::void example(std::nullptr_t) = delete;
  • 这是一个半丑陋的example() 模板版本,让它接受任何有效大小的const int[]nullptr 当然也被拒绝了。

标签: c++ arrays pointers language-lawyer


【解决方案1】:

其实

void example(int data[3])

void example(int data[])

void example(int* data)

你需要

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

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

【讨论】:

    【解决方案2】:

    当你有

    void example(int data[3])
    

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

    void example(int* data)
    

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

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

    强调我的

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-24
      • 2018-05-14
      • 1970-01-01
      • 1970-01-01
      • 2011-08-01
      • 2021-10-05
      • 1970-01-01
      相关资源
      最近更新 更多