I was trying to pass an array to a method. I tried following ways:
I dont understand why the last one (#3) gives warning. &ARRAY_NAME works without warnings in memset, memcpy etc. Why its a problem in custom method?
WARNING message:
functionTest.c:35:11: warning: passing argument 1 of ‘func2’ from incompatible pointer type [-Wincompatible-pointer-types]
35 | func2(&temp, ARRAY_SIZE);
| ^~~~~
| |
| unsigned char (*)[200]
functionTest.c:8:27: note: expected ‘unsigned char *’ but argument is of type ‘unsigned char (*)[200]’
8 | void func2(unsigned char* buf, int length)
CODE
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#define ARRAY_SIZE 200
void func2(unsigned char* buf, int length)
{
// Change data of any index
buf[0] = 100;
buf[10] = 200;
}
void func1()
{
unsigned char temp[ARRAY_SIZE];
// Initialize
memset(temp, 0, sizeof(temp));
for(int i = 0; i < ARRAY_SIZE; i++)
{
printf("\t%d", temp[i]);
}
printf("\n-----------------------------------------------\n");
printf("Address : %p\n", &temp);
printf("Address of 0th index : %p\n", &temp[0]);
printf("\n-----------------------------------------------\n");
// Pass array in func2
func2(&temp, ARRAY_SIZE); // WARNING
func2(&temp[0], ARRAY_SIZE); // NO WARNING
for(int i = 0; i < ARRAY_SIZE; i++)
{
printf("\t%d", temp[i]);
}
printf("\n-----------------------------------------------\n");
}
int main()
{
func1();
return 0;
}
As it is clear written in the error message
functionTest.c:8:27: note: expected ‘unsigned char *’ but argument is of type ‘unsigned char (*)[200]’
8 | void func2(unsigned char* buf, int length)
the function expects a pointer of the type unsigned char *
but the argument expression &temp
has the type unsigned char ( * )[200]
and there is no implicit conversion from one pointer type to another though values of the pointers are the same: the address of the extent of memory occupied by the array.
As for the functions memset
and memcpy
then they deal with pointers of the type void *
. For example the function memset
has the following declaration
void *memset(void *s, int c, size_t n);
And a pointer to object of other type can be implicitly converted to pointer of the type void *
.
From the C Standard (6.3.2.3 Pointers)
1 A pointer to void may be converted to or from a pointer to any object type. A pointer to any object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer.