【问题标题】:What is the purpose of sized array as function argument is c and c++?将大小数组作为函数参数的目的是c和c++?
【发布时间】:2021-07-07 11:53:20
【问题描述】:

考虑以下函数:

void func1(int unsized_array[]){}
void func2(int sized_array[10]){}
void func3(int *pointer){}

根据结果:

    std::cout << std::is_same<decltype(func1), decltype(func2)>::value << std::endl;
    std::cout << std::is_same<decltype(func2), decltype(func3)>::value << std::endl;
    std::cout << std::is_same<decltype(func3), decltype(func1)>::value << std::endl;

这三个函数的类型是一样的。同样在函数func2sizeofoperator 内部也不提供所有组合的数组元素的大小。

那么大小数组作为函数参数的目的是什么(如func2)?

【问题讨论】:

  • 这不是c,那为什么是标签呢?
  • @Devolus 但它来自 C。这里的 C++ 只是一种检测编译器考虑的方法。
  • @Devolus 我同意 std::is_same 不是 c 但最初我在 c 代码中看到了这种用法(大小数组作为函数参数)
  • 所有三个变体在 C 和 C++ 中都是相同的。没有像func2 那样声明数组大小的真正目的。该大小可能用于文档目的。
  • 是的,作为函数参数的数组会自动衰减为指针,所以这 3 个提案是相同的(这也是为什么在函数体内没有“看到”大小的原因,sizeof 将返回指针的大小,而不是数组的大小)

标签: c++ arrays function arguments


【解决方案1】:
  1. 由于数组声明符通常可能有大小表达式(如在参数中定义数组时或在声明包含数组作为子部分的参数时,例如指向数组的指针),它需要更多努力将其从语法中排除,而不是无害地留在语法中。 (C 中有许多结构可能不会产生任何效果,例如没有副作用的语句表达式 (3*4;)、没有副作用的逗号表达式的左操作数、具有空主体的函数或循环,等等。排除那些对语言没有影响的东西需要做很多工作。)

  2. 当存在static 关键字时,参数中的数组大小确实会改变含义; void func2(int asd[static 10]) 声明了一个函数,该函数必须传递一个指向至少十个元素中第一个元素的指针,这与其他声明的含义不同。 (这会使从数组参数声明的语法中排除大小表达式的问题更加复杂,因为有必要禁止裸大小,但不能使用static。)

  3. 数组大小对于函数实现者和函数用户来说可能是有用的文档。

  4. 评估数组大小。例如,如果定义为void func2(int asd[printf("Hello")]) {},则调用函数时将打印“Hello”。 (有些编译器可能不会这样做;C 标准对此并不清楚。)

  5. 如果编译器看到函数使用的元素数量超过规定数量,或者调用者传递的元素数量少于规定数量,则编译器可以使用 size 表达式发出警告。 (Clang 11 似乎不做前者,也不做后者,除非使用static。)

【讨论】:

  • 我不太同意3,因为这并不可靠,因此依赖此类文档很可能是错误的。
  • @Devolus:评论也不能保证,但可能是有用的文档。争论它们可能是错误的并不能反驳它们可能有用的事实。
  • 我知道。这就是为什么我通常尽量不评论代码,而是记录算法。 :)
  • @Devolus:算法的文档也不能保证。
  • @Devolus #3 是最好的理由。
【解决方案2】:

没有任何意义,因为它们都衰减为您正确识别的相同类型。对于 C++,此行为继承自 C。

就像将const 添加到非引用参数和其他关键字不会改变任何外部一样,它们都会导致void(int) 签名。

void foo1(int a) {}
void foo2(const int a) {}
void foo3(volatile int a) {}

但您可以使用实际有效的东西来代替int[10]

void func2(int(&asd)[10]) {}

这将只接受大小为 10 的 int 数组。您现在还可以使用 sizeof 在编译时获取数组大小,这对于 int[10] 显然是不可能的。

【讨论】:

  • 谢谢你提醒我void func2(int(&amp;asd)[10]) {}。我完全忘记了这一点
猜你喜欢
  • 2011-12-18
  • 1970-01-01
  • 1970-01-01
  • 2021-05-12
  • 2011-02-21
  • 2016-06-12
  • 1970-01-01
  • 1970-01-01
  • 2022-01-18
相关资源
最近更新 更多