atheaos
atheaos

Reputation: 729

Clarification on why this C code works

I'm learning C today. I've been coding in managed languages (Java, C#, Python, etc.) for some time now. I thought I was understanding the details of pointers, but then I wrote the following code that worked as expected, but generated an 'incompatible pointer type' warning.

void setText(char* output) {
    //code to set output to whatever, no problems here.
}

int main(int argc, const char* argv[]) {
    char output[10];

    setText(&output);

    //[EDITED] ...other test code which printf's and further manipulates output.

    return 0;
}

So I googled, and ended up changing the line

setText(&output);

to

setText(output);

which got rid of the warning. But now I don't know why the first one was working at all. I was sending the address of an address as far as I can tell (because char* x; is essentially the same as char x[];). What am I misunderstanding and why do both of these work?

Upvotes: 6

Views: 260

Answers (1)

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272467

The type of output is char [10], which decays to a char * in the context of a function call (which is why the second variant works).

The type of &output is char (*)[10], i.e. a pointer-to-array. This is not the same thing, hence the compiler warning. However, the value of &output (an address) is equivalent to the value of output (once it has decayed to a char *), so the end result is "as expected".

This may sound like pedantry, but there is a fairly important difference. Try the following:

void foo(const char *p)
{
    printf("%s\n", p);
}

int main(void)
{
    char output[][6] = { "Hello", "world" };

    foo(output[0] + 1);
    foo(&output[0] + 1);
}

Recommended reading is the C FAQ on arrays and pointers, in particular question 6.3 and 6.12.

Upvotes: 17

Related Questions