首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在传递数组时强制函数参数中的数组大小

在传递数组时强制函数参数中的数组大小
EN

Stack Overflow用户
提问于 2019-05-16 20:57:24
回答 2查看 2.7K关注 0票数 6

上下文

在C中,我有一个函数,它以数组作为参数。此参数用作此函数中的输出。输出总是相同的大小。我会:

  • 为任何阅读代码的人明确所需的大小(不过,它已经在函数注释中了),
  • 理想情况下,编译可以输出警告或错误,这样我就可以在编译时而不是运行时防止出现问题。

潜在的解决方案

我在这里发现:https://hamberg.no/erlend/posts/2013-02-18-static-array-indices.html,它看起来像一个解决方案,但是如果我试图传递一个比所需的大小更小的数组,那么在编译过程中我就无法得到警告或错误。

这是我的完整程序main.c:

代码语言:javascript
复制
void test_array(int arr[static 5]);

int main(void)
{
    int array[3] = {'\0'};

    test_array(array); // A warning/error should occur here at compilation-time
                       // telling me my array does not meet the required size.

    return 0;
}

void test_array(int arr[static 5])
{
    arr[2] = 0x7; // do anything...
}

与此博客相反,我使用gcc (7.4.0版)代替clang,并使用以下命令:

代码语言:javascript
复制
gcc -std=c99 -Wall -o main.out main.c

在我的代码中,我们可以看到test_array()函数需要一个5个元素数组。我正在传递一个三要素一。我希望编译器能给我一条关于这一点的信息。

问题

在C中,如何将函数参数强制为给定大小的数组?如果不是的话,它应该在编译时被注意到。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-05-16 21:04:21

如果将指针传递给数组而不是指向其第一个元素的指针,则会得到不兼容的指针警告:

代码语言:javascript
复制
void foo(int (*bar)[42])
{}

int main(void)
{
    int a[40];
    foo(&a);  // warning: passing argument 1 of 'foo' from incompatible pointer type [-Werror=incompatible-pointer-types]
    // note: expected 'int (*)[42]' but argument is of type 'int (*)[40]'

    int b[45];
    foo(&b);  // warning: passing argument 1 of 'foo' from incompatible pointer type [-Werror=incompatible-pointer-types]
    // note: expected 'int (*)[42]' but argument is of type 'int (*)[45]'
}

使用-Werror编译,使其成为一个错误。

哥德波特

票数 8
EN

Stack Overflow用户

发布于 2019-05-16 21:24:02

要测试正在传递的数组(非指针)的大小是否至少为5个元素,可以使用一个Static_assert,并且可以通过预处理器宏插入必要的_Static_assert

在该职能声明后插入:

代码语言:javascript
复制
#define test_array(arr) \
    do \
    { \
        _Static_assert(sizeof (arr) / sizeof *(arr) >= 5, "Array is too small."); \
       test_array(arr); \
    } while (0)

( do … while (0)是一种典型的定义宏的方法,可以像语句那样在语法上操作,这样就可以按照预期的;和flow来执行if语句等等)。

在该职能的定义之前插入:

代码语言:javascript
复制
#undef test_array

(如果函数有更多的用途,则必须插入#define的另一个副本。或者,函数可以在源文件的早期定义,然后是一个#define,这样就不需要进一步的#undef#define指令了。)

通常,这样的代码不太可能有用,因为程序经常将指针传递到数组的第一个元素(或数组中间的元素),并且不可能测试指针指向的空间中有多少个元素。因此,这只在代码中是有用的,在代码中,需要将数组作为参数提供给。这个要求不是由这个代码强制执行的。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56176512

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档