Adrian
Adrian

Reputation: 5681

warning: argument is incompatible with prototype (C) | address of char [] V.S. char**

I have a char array. I take its address and pass it to a function which accepts a double char pointer:

char result[1024+1];
memset(result, 0, sizeof(result));
executeGetQuery(query, &(result));

Function definition: int executeGetQuery(char * query, char ** queryResultData)

I get this compile time error

warning: argument #2 is incompatible with prototype:
prototype: pointer to pointer to char : line 1531
argument : pointer to array[1025] of char

I've always passed arrays as pointers in C before. Why am I getting this error? Is my compiler to blame?

EDIT: What is the fix?
EDIT2: I want the function to write something to the result array which is why I am passing a char** instead of char*. What is then another way, the way, to have a function write to a param which I pass in?

Upvotes: 2

Views: 1801

Answers (5)

pmg
pmg

Reputation: 108986

What is the fix?

In this case (you don't need the char **) use char * both in the prototype and the calling code

int executeGetQuery(char *query, char *queryResultData);
executeGetQuery(query, result);

I'd also include a size argument for protecting against buffer overflows

int executeGetQuery(char *query, char *queryResultData, size_t len);
executeGetQuery(query, result, sizeof result);

Edit:

to change the contents of the array do something like

int executeGetQuery(char *query, char *queryResultData, size_t len) {
    queryResultData[0] = 'H';  /* changing */
    queryResultData[1] = 'i';  /* the contents */
    queryResultData[2] = '\0'; /* of the array */
}

You can see the change in the calling function

executeGetQuery(NULL, result, sizeof result);
printf("result is now %s\n", result); /* should print "Hi" */

Upvotes: 2

Joachim Isaksson
Joachim Isaksson

Reputation: 181077

I'm not sure I can explain this 100% understandably, but the compiler is correct. A char** is a pointer to a memory location where a char pointer is stored.

You're not passing in a memory location storing a pointer, but instead try to pass in the address of a char array. You can manually assign the char array to a char pointer variable and use the address of that variable, but the compiler won't automatically create that temporary variable for you.

Upvotes: 1

fnl
fnl

Reputation: 2239

The function probably takes a char** because it will allocate the result buffer for you and use the return value to indicate errors, for example. Therefore, it will return the buffer by modifying a char-pointer provided by you. To do this it needs to access its memory location. That's why the function takes a char**. So to use it correctly, you would need to do:

char *foo;
executeGetQuery(query, &foo); // foo now points to the result buffer

Although you can use arrays in some contexts, where pointers are required in C, they are not the same. Your example makes it easy to see why: result is already an allocated memory region (most likely on the stack, if it's a local variable), so it can decay into a pointer pointing to its first element, but it cannot be a lvalue, like a pointer can.

Upvotes: 1

Nikolai Fetissov
Nikolai Fetissov

Reputation: 84239

char** here means the function will write into given memory location, something like:

int executeGetQuery(char * query, char ** queryResultData) {
    char* buffer = malloc( ... );
    /* get the query results into buffer */
    *queryResultData = buffer;
    ...
}

You can't do that with array, its address is not writable.

Upvotes: 3

ouah
ouah

Reputation: 145899

&result is not type char **. It is of type char (*)[1025].

You have to pass a pointer to a pointer to char to your function:

char *p;
executeGetQuery(query, &p);

Upvotes: 1

Related Questions