13

When I compiled the following code with gcc -Wall -pedantic -ansi -std=c89, it compiled successfully without giving an error at the pointer assignment. Note that I convert from int (*)[4] to int (*)[].

int arr[4];
int (*p_arr)[] = &arr;

Assuming that there is some reason for allowing this (incompatible?) assignment, when I try to use it, the compiler gives incomplete type error error: invalid application of ‘sizeof’ to incomplete type ‘int[]’.

(void) sizeof(*p_arr);

This error makes me think what is the use of allowing the previous pointer assignment p_arr = &arr? Is this assignment allowed as per the standard?

I have used incomplete struct/union type (usually for forward declaration) and also come across the error incomplete array element type. But this incomplete array type is new to me. Is it possible in C standard and has a use case?

Jason
  • 36,170
  • 5
  • 26
  • 60
user1969104
  • 2,340
  • 14
  • 15
  • 2
    Decide on one language. C and C++ are different. – Lundin Nov 18 '15 at 13:40
  • @Lundin I understand. I always chose one tag so far. But which tag to choose if we are asking a question about difference between `C` and `C++`? Do you think these tags are meant to be absolutely exclusive or just meant to be some search terms? – user1969104 Nov 18 '15 at 14:06
  • @user1969104 Are you asking about a difference between C and C++? It doesn't seem so. If you were, it'd be fine to add both tags and I'm sure Lundin wouldn't have added this comment. – The Paramagnetic Croissant Nov 18 '15 at 14:24
  • I moved the EDIT part to a new question [Difference in incomplete array pointer conversion rules between C and C++](http://stackoverflow.com/questions/33782518/difference-in-incomplete-array-pointer-conversion-rules-between-c-and-c) as suggested by @Lundin. I will add both the tags there. Thanks. – user1969104 Nov 18 '15 at 14:27

1 Answers1

6

This assignment didn't give any error because their types are compatible because arrays of unknown bound are compatible with any array of compatible element type. (For reference)-

int (*p_arr)[] = &arr;

But gives error on passing it as operand to sizeof operator because *p_arr is of incomplete type and you are not supposed to use incomplete types as operands to sizeof operator.

N1570 6.5.3.4

1 The sizeof operator shall not be applied to an expression that has function type or an incomplete type, to the parenthesized name of such a type, or to an expression that designates a bit-field member[...].

Now what you can use it, here is a simple example -

#include <stdio.h>

int main(void){
    int arr[4]={1,2,3,4};
    int a[6]={1,2,3,3,1,1}; 
    int (*p_arr)[] = &arr;
    for(int i=0;i<4;i++)
       printf("%d",(*p_arr)[i]);
    printf("\n");
    p_arr=&a;
    for(int i=0;i<6;i++)
       printf("%d",(*p_arr)[i]);
    return 0;
}
ameyCU
  • 16,489
  • 2
  • 26
  • 41
  • 2
    @user1969104 Please don't suddenly change the question with an edit. If you have a new question, then post a new question. As it turns out, your second question is related to the difference in pointer conversion rules between C and C++, which is not even related to pointers to incomplete type. Consider the example `intptr = voidptr;` in C and C++, you'll get the very same issue. – Lundin Nov 18 '15 at 13:50