为什么要在函数头中声明C数组参数的大小?

时间:2021-05-29 21:30:26

Can anyone enlighten me as to why I should bother to specify the size of a C array argument in a function header? For example:

任何人都可以告诉我为什么我应该在函数头中指定C数组参数的大小?例如:

void foo (int iz[6]) { iz[42] = 43; }

With:

附:

int is[2] = {1,2,3};

we get a useful error. Perhaps it helps with commenting/documentation?

我们得到一个有用的错误。也许它有助于评论/文档?

4 个解决方案

#1


11  

Can anyone enlighten me as to why I should bother to specify the size of a C array argument in a function header? For example:

任何人都可以告诉我为什么我应该在函数头中指定C数组参数的大小?例如:

void foo (const char sz[6]) { sz[42] = 43; }

void foo(const char sz [6]){sz [42] = 43; }

IMO, you shouldn't. When you try to pass an array to a function, what's really passed is a pointer to the beginning of the array. Since what the function receives will be a pointer, it's better to write it to make that explicit:

IMO,你不应该。当您尝试将数组传递给函数时,实际传递的是指向数组开头的指针。由于函数接收的是指针,因此最好将其写为显式:

void foo(char const *sz)

Then, since it's now clear that the function has been given no clue of the size, add that as a separate parameter:

然后,由于现在很清楚该函数没有给出大小的线索,所以将其添加为单独的参数:

void foo(char const *sz, size_t size)

#2


9  

The only meaningful reason to do that is for documentation purposes - to tell the future users that functions expect to receive an array of at least that many elements. But even that is a matter of convention - something that you have to agree upon with other users in advance. The language (the compiler) ignores that size anyway. Your function declaration is equivalent to void foo(int iz[]) and to void foo(int *iz).

这样做的唯一有意义的原因是出于文档目的 - 告诉未来的用户,函数期望接收至少那么多元素的数组。但即使这是一个常规问题 - 您必须提前与其他用户达成一致意见。语言(编译器)无论如何都会忽略该大小。你的函数声明等同于void foo(int iz [])和void foo(int * iz)。

The only way to make it somewhat meaningful for the compiler is to declare it as

使编译器有意义的唯一方法是将其声明为

void foo (int iz[static 6])

which acts as a promise to the compiler that the array will have at least 6 elements, meaning that the compiler will be able to optimize that code using that assumption. Moreover, if you really want to adopt the convention mentioned above, it makes more sense to declare array parameter sizes with static specifically, since the language explicitly defines the semantics of this construct.

作为对编译器的承诺,该数组将具有至少6个元素,这意味着编译器将能够使用该假设优化该代码。而且,如果你真的想采用上面提到的约定,那么用特定的静态声明数组参数大小更有意义,因为语言显式定义了这个结构的语义。

What you mean by "we get a useful error" is not clear to me. The code

您对“我们得到一个有用的错误”的意思并不清楚。代码

int is[2] = {1,2,3};
is[42] = 42;

does not contain any constraint violations. It produces undefined behavior, but it is not required to produce a diagnostic message during compilation. In other words, no, we don't get any "useful error" from this.

不包含任何约束违规。它会产生未定义的行为,但在编译期间不需要生成诊断消息。换句话说,不,我们没有得到任何“有用的错误”。

#3


6  

It's a comment. Arrays are demoted to pointers in function parameters. Comments can still be useful however, even if the compiler doesn't read them.

这是一个评论。数组被降级为函数参数中的指针。但是,即使编译器没有读取它们,注释仍然有用。

#4


0  

It is a useful comment when you want to tell to client code that it must pass an array of defined size, i.e:

当你想告诉客户端代码它必须传递一个定义大小的数组时,这是一个有用的注释,即:

void foo(const char bar[5]);
/* It is expected that foo function receives an array of size 5 */

Yet, documentation doesn't replace in code checks:

但是,文档不会替代代码检查:

void foo(const char bar[5])
{
    if (!bar) error();
    if (strlen(bar) != 4) error();
    /* ... */
}

#1


11  

Can anyone enlighten me as to why I should bother to specify the size of a C array argument in a function header? For example:

任何人都可以告诉我为什么我应该在函数头中指定C数组参数的大小?例如:

void foo (const char sz[6]) { sz[42] = 43; }

void foo(const char sz [6]){sz [42] = 43; }

IMO, you shouldn't. When you try to pass an array to a function, what's really passed is a pointer to the beginning of the array. Since what the function receives will be a pointer, it's better to write it to make that explicit:

IMO,你不应该。当您尝试将数组传递给函数时,实际传递的是指向数组开头的指针。由于函数接收的是指针,因此最好将其写为显式:

void foo(char const *sz)

Then, since it's now clear that the function has been given no clue of the size, add that as a separate parameter:

然后,由于现在很清楚该函数没有给出大小的线索,所以将其添加为单独的参数:

void foo(char const *sz, size_t size)

#2


9  

The only meaningful reason to do that is for documentation purposes - to tell the future users that functions expect to receive an array of at least that many elements. But even that is a matter of convention - something that you have to agree upon with other users in advance. The language (the compiler) ignores that size anyway. Your function declaration is equivalent to void foo(int iz[]) and to void foo(int *iz).

这样做的唯一有意义的原因是出于文档目的 - 告诉未来的用户,函数期望接收至少那么多元素的数组。但即使这是一个常规问题 - 您必须提前与其他用户达成一致意见。语言(编译器)无论如何都会忽略该大小。你的函数声明等同于void foo(int iz [])和void foo(int * iz)。

The only way to make it somewhat meaningful for the compiler is to declare it as

使编译器有意义的唯一方法是将其声明为

void foo (int iz[static 6])

which acts as a promise to the compiler that the array will have at least 6 elements, meaning that the compiler will be able to optimize that code using that assumption. Moreover, if you really want to adopt the convention mentioned above, it makes more sense to declare array parameter sizes with static specifically, since the language explicitly defines the semantics of this construct.

作为对编译器的承诺,该数组将具有至少6个元素,这意味着编译器将能够使用该假设优化该代码。而且,如果你真的想采用上面提到的约定,那么用特定的静态声明数组参数大小更有意义,因为语言显式定义了这个结构的语义。

What you mean by "we get a useful error" is not clear to me. The code

您对“我们得到一个有用的错误”的意思并不清楚。代码

int is[2] = {1,2,3};
is[42] = 42;

does not contain any constraint violations. It produces undefined behavior, but it is not required to produce a diagnostic message during compilation. In other words, no, we don't get any "useful error" from this.

不包含任何约束违规。它会产生未定义的行为,但在编译期间不需要生成诊断消息。换句话说,不,我们没有得到任何“有用的错误”。

#3


6  

It's a comment. Arrays are demoted to pointers in function parameters. Comments can still be useful however, even if the compiler doesn't read them.

这是一个评论。数组被降级为函数参数中的指针。但是,即使编译器没有读取它们,注释仍然有用。

#4


0  

It is a useful comment when you want to tell to client code that it must pass an array of defined size, i.e:

当你想告诉客户端代码它必须传递一个定义大小的数组时,这是一个有用的注释,即:

void foo(const char bar[5]);
/* It is expected that foo function receives an array of size 5 */

Yet, documentation doesn't replace in code checks:

但是,文档不会替代代码检查:

void foo(const char bar[5])
{
    if (!bar) error();
    if (strlen(bar) != 4) error();
    /* ... */
}