简体   繁体   English

在 C 中传递指向 arrays 的指针的正确方法是什么?

[英]What is the proper way of passing pointers to arrays in C?

Take this piece of code as an example:以这段代码为例:

#include <stdio.h>
void print_array(size_t size, unsigned (*myarray)[])
{
    printf("Array size: %lu\n", size);
    for (size_t i = 0; i < size; ++i)
            printf("%u ", (*myarray)[i]);
    printf("\n");
}
int main() {
    unsigned myarray[] = { 9, 8, 7, 6, 5 };
    print_array(sizeof(myarray) / sizeof(unsigned), &myarray);
    return 0;
}

When compiled with clang analyzer (via gcc 10.1.0) the warning is:使用 clang 分析器(通过 gcc 10.1.0)编译时,警告为:

src/main.c:7:3: warning: 2nd function call argument is an uninitialized value
            printf("%u ", (*myarray)[i]);
            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~

The output is: output 是:

Array size: 5
9 8 7 6 5 

What is the mistake in this piece of code and what is the proper way to pass pointers to arrays in C?这段代码有什么错误,在 C 中传递指向 arrays 的指针的正确方法是什么?

You can simply pass a pointer and use the fact that array variables represent the address where their first element starts.您可以简单地传递一个指针并使用数组变量表示其第一个元素开始的地址这一事实。 It seems using pedantic with clang, makes a lot of assumptions about what could the function argument be pointing to, so it complains.似乎对 clang 使用迂腐,对 function 参数可能指向什么做了很多假设,所以它抱怨。

void print_array(size_t size, const unsigned *myarray)
{
    printf("Array size: %lu\n", size);
    for (size_t i = 0; i < size; ++i)
            printf("%u ", myarray[i]);
    printf("\n");
}

int main() {
    unsigned myarray[] = { 9, 8, 7, 6, 5 };
    print_array(sizeof(myarray) / sizeof(unsigned), myarray);
    return 0;
}

This seems like a false positive.这似乎是一个误报。 There is no problem with the code - although the style is a bit exotic, it is all valid C.代码没有问题 - 虽然风格有点异国情调,但都是有效的 C。

If the remark is about actual missing initialization, it could be related to the tool not checking the caller.如果评论是关于实际缺少初始化,则可能与工具未检查调用者有关。 But even if the analyser only takes the local translation unit in consideration, it can't go off and assume that passed variables are uninitialized by default.但是即使分析器只考虑本地翻译单元,它也不能 go 关闭并假设传递的变量默认未初始化。 That would be a very strange assumption.那将是一个非常奇怪的假设。

Perhaps the analyser got spooked that you are actually passing a unsigned (*myarray)[5] to a function expecting a unsigned (*myarray)[] (pointer to incomplete type, an array of unspecified size).也许分析器被吓到了,您实际上是在将unsigned (*myarray)[5]传递给 function 并期望unsigned (*myarray)[] (指向不完整类型的指针,未指定大小的数组)。 You could try to change the parameter to unsigned (*myarray)[size]) and see if it makes the tool happier.您可以尝试将参数更改为unsigned (*myarray)[size])并查看它是否使工具更快乐。

Edit: the array pointer types are compatible though, so the tool shouldn't complain for that reason either.编辑:虽然数组指针类型是兼容的,所以该工具也不应该因为这个原因而抱怨。 As per C17 6.7.6.2/6, one or both of the array types can leave out the size specifier and still be compatible:根据 C17 6.7.6.2/6,一种或两种数组类型可以省略大小说明符并且仍然兼容:

For two array types to be compatible, both shall have compatible element types, and if both size specifiers are present, and are integer constant expressions, then both size specifiers shall have the same constant value.对于要兼容的两个数组类型,两者都应具有兼容的元素类型,并且如果两个大小说明符都存在,并且是 integer 常量表达式,则两个大小说明符应具有相同的常量值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM