Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is happening with the pointers in this snippet?

Tags:

c

pointers

I am curious as to why this is an error and what the error message means. Here is some code:

int *x[] = {"foo", "bar", "baz"};
int *y[] = {"foo", "bar", "baz"};

x = y;

I try to compile and I get this:

error: incompatible types when assigning to type ‘char *[3]’ from type ‘char **’

Question #1 why is this an error? and Question #2 why are the types different?

like image 875
Mike Avatar asked Apr 18 '10 03:04

Mike


3 Answers

As written, there are quite a few problems. First, the array literals are of type char*[], while x and y are of type int*[]. Second, you can't assign arrays directly, as they are in effect constant pointers.

like image 58
Max Shawabkeh Avatar answered Sep 24 '22 18:09

Max Shawabkeh


There is an incompatible types error because you are assigning arrays of strings (type char * in C) to arrays of pointers to ints (such as int *x[]). The error message given by the compiler is a little confusing because C does a lot behind the scenes to try to convert variables from one type to another.

As chars are represented internally as numbers (letters correspond to their ASCII values), C is able to convert characters to ints, so it attempts to treat variables x and y as arrays of pointers to chars instead of ints, hence the char *[3]. It sees {"foo", "bar", "baz"} as type char ** because strings are type char * and arrays essentially stored as pointers in C, so it is a pointer to char *, or char **.

While this doesn't completely relate to your question, I also wonder what you're trying to do with x = y; As it is written, that will make x point to the same array as y, leaving the array that x used to point to inaccessible. To check whether two variables in C are equal, you would use the == operator. Testing equality isn't as simple for arrays or strings, but that's completely outside the scope of this question.

like image 23
gmoomau Avatar answered Sep 20 '22 18:09

gmoomau


It is an error, because an array is a non-modifiable lvalue - meaning you can't assign directly to it. You can only modify the array's members individually.

The types are different because if an array is used in a context where an lvalue is not required, it is evaluated to a pointer to its first element (somearray becomes effectively &somearray[0]).

Since the array y is used in such a context, it is evaluated as the address of its first element, which has type int **. Since the array x is in an lvalue context, it is evaluated as an array (int *[3]). (Your error message doesn't actually match your code - I suspect your arrrays are actually arrays of char *).

("lvalue context" means, pretty much, one of: The left hand side of an assignment operator (which is where the name comes from); the subject of the sizeof operator; or the subject of the & operator).

like image 35
caf Avatar answered Sep 23 '22 18:09

caf