Search code examples
c++arrayspointerstypedefreinterpret-cast

Array typedef pointer decomposition in function parameter


I have a simple array typedef

typedef char myString[8];

And one function that takes a myString and another that takes a myString*. Interestingly, both of these functions have the exact same implementation and produce the exact same output:

void foo(myString s){
    std::string stdstr(reinterpret_cast<char*>(s), 8);
    std::cout << stdstr << std::endl;
}

void bar(myString* s){
    std::string stdstr(reinterpret_cast<char*>(s), 8);
    std::cout << stdstr << std::endl;
}

foo makes sense to me, but I do not understand what is happening in bar. Why is it valid to cast a myString* to char* in? Isn't the underlying type char**? My guess is there is some syntactic sugar at play, but I can't find any references to this particular case.

Note that changing the functions to void foo(char* s) and void bar(char** s) produces different outputs, as expected.

Working example here


Solution

  • You introduced the alias myString for an array type

    typedef char myString[8];
    

    So this function declaration

    void bar(myString* s){
    

    is equivalent to the declaration

    void bar( char ( *s )[8] ){
    

    If you have an array declared for example like

    char str[8] = "1234567";
    

    and are calling the function bar like

    bar( &str );
    

    then the value of the expression &str is the address of the extent of memory occupied by the array str. That is it is the address of the first element of the array str though the type of the expression is char( * )[8] instead of char *. That is the addresses of expressions &str, str and &str[0] are the same.

    So within the function this value of the address (the address of the first element of the passed character array) is interpreted as having the type char *.

    std::string stdstr(reinterpret_cast<char*>(s), 8);
    

    and you gets the address of the first element of the array of the type char *.

    Of course you could just write instead

    std::string stdstr( *s, 8);