The strcat
function is declared as (C17 7.24.3.1):
char *strcat(char * restrict s1,
const char * restrict s2);
Where the important part for the sake of this discussion is that the function expects char*
for both parameters. Though we can note that a char*
can be assigned to a const char*
, but not the other way around.
If we look at the correct use, strcat(buff, temp);
, then both buff
and temp
in that expression are arrays. But in most cases when an array is used in an expression, it "decays" into a pointer to it's first element, it becomes a char*
in this case.
Formally this "decay" is defined as (C17 6.3.2.1):
Except when it is the operand of the sizeof
operator, or the unary &
operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue.
However when you type &temp
, you stumble upon one of the above mentioned exceptions to this "array decay" rule, namely when used with the unary &
.
So instead of a char*
we end up with "address of a char [3]
". Which has to be expressed with a special pointer type used when pointing at arrays, char (*)[3]
, known as "pointer to array" or "array pointer".
C has pretty strict rules regarding implicit pointer conversions - it will not accept that a char(*)[3]
is passed to a parameter expected to be const char*
- they are incompatible pointer types - it is not a valid form of assignment.
When you know all of this, the compiler error is actually quite self-explanatory.