-1

I am expanding my knowledge of arcane C usage, especially with strange pointer types. I found a site with some examples and I've been trying them out. However, after playing with some of these examples, I found some strange behaviour relating to a pointer to an array. Here is the code:

int test = 45;
int *testp = &test;
int (*p)[1];
p = &testp;
printf("%d\n", **p);

This code outputs 2686744 (which I can make no sense of). My logic is as follows: an array is just a glorified pointer. I can make a pointer and call it an array of 1 if I like. So when I create the pointer testp, I expect it to function as an array of 1 int. Furthermore, I would expect the line int (*p)[1]; to create an int** variable. However, there is something even worse about the whole thing. Here is a modified version of the above code:

int test[1] = {45};
int (*p)[1];
p = &test;
printf("%d\n", **p);

This outputs 45, as expected. So, my question is, what is the difference between these two snippets that causes the first to output garbage?

Thanks

5
  • 1
    p is a pointer to an array, not a pointer to a pointer. Commented Aug 23, 2014 at 16:34
  • But shouldn't a pointer to an array function as a pointer to a pointer? Commented Aug 23, 2014 at 16:36
  • 3
    No, even though pointers and array may seem identical they are not. Commented Aug 23, 2014 at 16:37
  • 2
    No, the array-to-pointer decay (lvalue conversion) only happens to the outermost type. So, an array of elements of type "T" decays to a pointer to type T in most expressions, but an array of elements of type "array of Ts" only decays to "pointer to array of Ts", not to "pointer to pointer to Ts". This is certainly a duplicate, I'm looking for a good one… Commented Aug 23, 2014 at 16:39
  • 1
    This is at least a candidate, maybe answering your question… Commented Aug 23, 2014 at 16:48

1 Answer 1

2

This code snippet is invalid and shall not be compiled

int test = 45;
int *testp = &test;
int (*p)[1];
p = &testp;
printf("%d\n", **p);

The type of expression &testp is int ** while in the left side of the assignment there is an object of type int (*)[1]. There is no implicit conversion from one type to enother.

Nevertheless dereferencing p in the function call

printf("%d\n", **p);

that is *p will give array of type int[1] However the value stored in *p is the value of testp. Thus the only element of the array is the value stored in testp that is the address of test (provided that sizeof( int * ) is equal to sizeof( int ).

So the output of the function is the address of test.

The second code snippet is valid. *p is an array with one element and **P gives the value of the first element of the aray.

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

4 Comments

I understand now, thank you. However, it's strange that gcc compiles the first snippet anyway...
@Mahkoe: gcc compiles virtually everything which is compilable somehow, by default, that is, it compiles some programmes, which are invalid according to the C standard. You've got a warning for it, I think.
@Mahkoe i got error message error: assignment from incompatible pointer type when compiled the code with gcc.
@VladfromMoscow: I'm quite sure this is only a warning if not compiled with -Werror or -pedantic-errors or some other options…

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.