4

In C, why is it that I'm able to pass character arrays to functions that take a char * as an argument, but I cannot pass the address of an array to functions that take a char **?

UPDATE: Interestingly, changing the argument type to char* qux[12] doesn't change the compiler warning at all

For example:

#include <stdio.h>

void foo(char* qux) { puts(qux); }
void bar(char** qux) { puts(*qux); }
void baz(char* qux[12]) { puts(*qux); }

int main() {
    char str[12] = "Hello there";

    foo(str);
    bar(&str); // Compiler warning
    baz(&str); // Same compiler warning

    return 0;
}

In the second case, I get a compiler warning:

warning: incompatible pointer types passing 'char (*)[12]' to
         parameter of type 'char **' [-Wincompatible-pointer-types]

What's going on here?

9
  • They're different types. Ask yourself: What is the size of *qux? Commented Apr 27, 2018 at 4:59
  • Try to understand basic difference between single and double pointers Commented Apr 27, 2018 at 5:03
  • 1
    I feel there should be a dupe for this question. Commented Apr 27, 2018 at 5:04
  • @ThiruShetty I understand the difference between single and double pointers, however I wasn't aware of array decay as mentioned in Someprogrammerdude's answer Commented Apr 27, 2018 at 5:05
  • I've tried quite a few search terms but please let me know if you find any @MFisherKDX ! Commented Apr 27, 2018 at 5:05

2 Answers 2

5

Arrays naturally decays to pointers to their first element. So in the call foo(str) it's really the same as foo(&str[0]). This is of type char * so it's all okay.

Now the second call, the one to bar, is a different matter. When you use &str you don't get a pointer to the arrays first element, you get a pointer to the array itself. And as the compiler noted, this is of type char (*)[12], which is very different from (and incompatible with) char **.

Lastly, when you declare baz you say that the argument is of type char *[12], that is you have an array or 12 pointers to char, not that you have a pointer to an array of 12 char. Furthermore, due to the array decay to pointer thing, char *[12] is actually the same as char **.

Sign up to request clarification or add additional context in comments.

5 Comments

Oh I guess I didn't know about array decay, that's interesting. Is there a way to make that argument be a pointer to an array of 12 char instead of the other way around?
try this way. char *qux1 = NULL; qux1=qux; bar(&qux1);
@BrunoEly I just told it to you, and it's also part of the error message: "... passing 'char (*)[12]' to...". Use e.g. char (*qux)[12] and you have a pointer to an array of 12 char. However, passing pointers to arrays like that is often not needed, passing a simple char * pointing to the first element is the common use-case.
@Someprogrammerdude got it! Yeah that's how I usually do it, I just couldn't figure out what that error message meant and it's been bugging me for a while. Thanks for the explanation
"Furthermore, due to the array decay to pointer thing, char *[12] is actually the same as char **." An array is not the same as a pointer. An expression of array type is implicitly converted to a pointer to its first element in many contexts, but not all.
2

In C, char * represents a pointer to a contiguous sequence of characters. A contiguous sequence of characters with a null termination is what we call a string in C.

char ** is a pointer to a contiguous sequence of strings, and since each string is a contiguous sequence of characters terminated by a null ('\0') character, char ** represents a contiguous sequence to a contiguous sequence of null terminated characters.

Your declaration:

 char str[12] = "Hello there";

Declares str to be an array of characters of length 12, and it is initialized to the 12 characters {'H','e','l','l','o',' ','t','h','e','r','e','\0'}. This is compatible with the parameter in foo(), but not with bar and baz both of which expect a contiguous sequence of pointers to strings. That is why those two give you a compiler warning because the parameter is incompatible with the arguments passed in.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.