Clarification on why this C code works
Question: 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?


Answer: 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](http://c-faq.com/aryptr/), in particular question 6.3 and 6.12.

