【问题标题】:Passing a parameter of type int(*)[] in C++在 C++ 中传递 int(*)[] 类型的参数
【发布时间】:2020-11-12 06:51:24
【问题描述】:

以下程序在 gcc 但不是 g++ 编译:

void foo(int (*x)[])
{
    // do something
}

int main()
{
    int x[3];

    foo(&x);  // g++ error: cannot convert ‘int (*)[3]’ to ‘int (*)[]’

    return 0;
}

我正在尝试使用一个用 ANSI C 编写的库,所以我无法控制 foo 的接口。

为什么这是有效的 C 而不是有效的 C++ 已在 this QA 中讨论过。我的问题是:如何使用 C++ 中的此类声明调用函数 foo

【问题讨论】:

  • 你认为int(*)[] 比简单的int* 做得“更好”吗?
  • 我无法谈论在 C 中的合法性,但是 C++ 编译器会在您传递引用数组时看到您的声明 foo(&x),而不是您对接受数组的 foo(int (*x)[]) 的定义整数。这就是为什么没有 C++ 编译器会编译示例中的代码的原因。
  • 当你有一个指向数组的指针时,数组的大小是类型的一部分。你不能有“指向任何数组的指针”。
  • @alteredinstance x 是一个数组,而不是指向数组的指针,因此,&x 确实是指向该数组的指针。这里没有引用也没有指针数组。
  • @HugoBurd 我会重新打开,你可以编辑

标签: c++ c


【解决方案1】:

以下程序编译...不是 g++:

这是因为 g++ 在 C++ 语言中编译。并且显示的程序在 C++ 语言中格式不正确。

特别是,问题在于函数参数是一个指向未知边界数组的指针,但传递的参数是一个指向长度为 3 的数组的指针。后者不能隐式转换为前者。

那么如何在 C++ 中获得指向未指定数组的指针呢?!

例子:

extern int arr_ext[ ];
       int arr_3  [3];

int (*ptr)[] = &arr_ext;
ptr          = reinterpret_cast<int (*)[]>(&arr_3); // †

† 在 C++ 中,使用这个重新解释的指针可能在技术上是 UB,而不是重新解释为指向长度为 3 的数组的指针,但如果使用发生在 C 库中,谁知道......跨语言边界的规则是有时很模糊。


相比之下,在 C 中,指向一种类型的指针可以隐式转换为指向另一种兼容类型的指针。并且未知边界的数组与任何大小、相同元素类型的数组兼容。


在 C++ 中允许相同的隐式转换似乎存在一个活跃的问题:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4325.html#118

【讨论】:

  • 那么如何在 C++ 中获取指向未指定数组的指针?!
  • @AnttiHaapala 添加了一个示例。
  • 外部是获取 C++ 中未指定数组指针的唯一方法吗?
  • @HugoBurd Reinterpret 演员是另一个。我不知道它是否会很好地定义。
  • @HugoBurd 您实际上并不需要将指针传递给数组本身。传递指向其第一个元素的指针就足够了,例如:void foo(int *x) { ... } int main() { int x[3]; foo(x); return 0; }
猜你喜欢
  • 2013-10-15
  • 2010-12-19
  • 1970-01-01
  • 2021-08-07
  • 1970-01-01
  • 2018-12-16
  • 1970-01-01
  • 1970-01-01
  • 2020-09-13
相关资源
最近更新 更多