使用地址运算符在 ac 函数中传递数组会发出警告

bla*_*bug 0 c arrays pointers gcc-warning implicit-conversion

我试图将数组传递给方法。我尝试了以下方法:

\n
    \n
  1. func2(ARRAY_NAME, length) => 有效,无警告
  2. \n
  3. func2(&ARRAY_NAME[0], length) => 有效,无警告
  4. \n
  5. func2(&ARRAY_NAME, length) => 有效,但有警告
  6. \n
\n

我不明白为什么最后一个(#3)发出警告。&ARRAY_NAME 在 memset、memcpy 等中工作时没有警告。为什么它在自定义方法中存在问题?

\n

警告信息:

\n
functionTest.c:35:11: warning: passing argument 1 of \xe2\x80\x98func2\xe2\x80\x99 from incompatible pointer type [-Wincompatible-pointer-types]\n   35 |     func2(&temp, ARRAY_SIZE);\n      |           ^~~~~\n      |           |\n      |           unsigned char (*)[200]\nfunctionTest.c:8:27: note: expected \xe2\x80\x98unsigned char *\xe2\x80\x99 but argument is of type \xe2\x80\x98unsigned char (*)[200]\xe2\x80\x99\n    8 | void func2(unsigned char* buf, int length)\n
Run Code Online (Sandbox Code Playgroud)\n

代码

\n
#include <stdio.h>\n#include <stdint.h>\n#include <string.h>\n\n\n#define ARRAY_SIZE 200\n\nvoid func2(unsigned char* buf, int length) \n{\n    // Change data of any index\n    buf[0] = 100;\n    buf[10] = 200;\n}\n\nvoid func1()\n{\n    unsigned char temp[ARRAY_SIZE]; \n    // Initialize\n    memset(temp, 0, sizeof(temp));\n\n    for(int i = 0; i < ARRAY_SIZE; i++)\n    {\n        printf("\\t%d", temp[i]);\n    }\n\n    printf("\\n-----------------------------------------------\\n");\n\n    printf("Address : %p\\n", &temp);\n    printf("Address of 0th index : %p\\n", &temp[0]);\n    \n    printf("\\n-----------------------------------------------\\n");\n\n    // Pass array in func2  \n\n    func2(&temp, ARRAY_SIZE); // WARNING\n\n    func2(&temp[0], ARRAY_SIZE); // NO WARNING\n\n    for(int i = 0; i < ARRAY_SIZE; i++)\n    {\n        printf("\\t%d", temp[i]);\n    }\n\n    printf("\\n-----------------------------------------------\\n");\n}\n\nint main()\n{\n    func1();\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

Vla*_*cow 5

正如错误消息中明确写的那样

\n
functionTest.c:8:27: note: expected \xe2\x80\x98unsigned char *\xe2\x80\x99 but argument is of type \xe2\x80\x98unsigned char (*)[200]\xe2\x80\x99\n    8 | void func2(unsigned char* buf, int length)\n
Run Code Online (Sandbox Code Playgroud)\n

该函数需要该类型的指针unsigned char *,但参数表达式&temp具有该类型unsigned char ( * )[200],并且没有从一种指针类型到另一种指针类型的隐式转换,尽管指针的值相同:数组占用的内存范围的地址。

\n

至于函数memsetmemcpy然后它们处理类型的指针void *。例如函数memset具有以下声明

\n
void *memset(void *s, int c, size_t n);\n
Run Code Online (Sandbox Code Playgroud)\n

并且指向其他类型的对象的指针可以隐式转换为类型的指针void *

\n

来自 C 标准(6.3.2.3 指针)

\n
\n

1 指向 void 的指针可以与指向任何对象类型的指针相互转换。指向任何对象类型的指针都可以转换为指向 void 的指针,然后再转换回来;结果应等于\原始指针。

\n
\n