Search code examples
c++cpointersimplicit-conversionexplicit-conversion

Why can't we directly assign arr to pointer to array


I have an array of 5 integers. arr and &arr is same address. So why number 2 gives compilation error and and 3 works fine.

  int arr[5] = {1,2,3,4,5};
  1. int *p = arr;
  2. int (*p1)[5] = arr //Compilation Error
  3. int (*p1)[5] = &arr; //Works fine.
  
     arr = 0x61fdf0 and &arr= 0x61fdf0

Solution

  • The problem is that the initialized object and the initializer have different pointer types and there is no implicit conversion from one pointer type to another.

    In this declaration

    int (*p1)[5] = arr;
    

    the initialized object has the type int ( * )[5] while the initializer has the type int * due to the implicit conversion of the array designator to a pointer to its first element.

    You have to write

    int (*p1)[5] = &arr
    

    Or for example

    int ( *p1 )[5] = reinterpret_cast<int ( * )[5]>( arr );
    

    Here is a demonstrative program.

    #include <iostream>
    
    int main() 
    {
        int arr[5] = {1,2,3,4,5};   
        
        int ( *p1 )[5] = reinterpret_cast<int ( * )[5]>( arr );
    
        std::cout << "sizeof( *p1 ) = " << sizeof( *p1 ) << '\n';
        
        return 0;
    }
    

    The program output is

    sizeof( *p1 ) = 20
    

    Objects can have equal values but different types.

    Consider an another case.

    Let's assume that you have an object of a structure type

    struct A
    {
        int x;
    } a;
    

    in this case &a and &a.x have the same values but the types of the expressions are different. You may not write for example

    int *p = &a;
    

    the compiler will issue an error. But you can write

    int *p = ( int * )&a;
    

    or

    int *p = reinterpret_cast<int *>( &a );
    

    Here is a demonstrative program.

    #include <iostream>
    #include <iomanip>
    
    int main() 
    {
        struct A
        {
            int x;
        } a = { 10 };
        
        std::cout << std::boolalpha << ( ( void * )&a.x == ( void * )&a ) << '\n';
        
        int *p = reinterpret_cast<int *>( &a );
        
        std::cout << "*p = " << *p << '\n';
        
        return 0;
    }
    

    The program output is

    true
    *p = 10
    

    As for your one more question in a comment

    Can you decode this in simple language to understand int** p = new int*[5];

    then in this expression with the operator new

    new int*[5]
    

    there is allocated memory for an array with 5 elements of the type int *. The expression returns a pointer to the first element of the array. A pointer to an object of the type int * (the type of elements of the allocated array) will have the type int **.