I have noticed that constness on a typedef'ed pointer loses its ability to be converted implicitly to a const type of the un-typedef'ed type.
Since I am clearly lacking proper vocab to explain the issue, I'll show some examples.
The following code fails to compile with GCC 8.3.0
typedef char* char_ptr;
void myFunc(const char_ptr param);
void test() {
const char str[] = "Hello, World!";
myFunc(str);
}
It gives the following error:
error: invalid conversion from ‘const char*’ to ‘char_ptr’ {aka ‘char*’} [-fpermissive] myFunc(str);
I'm not looking for a workaround. I know many ways to solve this, such as casting the type or changing the function declaration.
I'd like to understand why I get this error, and why it only happens with const of a typedef'ed pointer type.
I have narrowed down some use-cases to try to understand when the compiler thinks that types are identical https://ideone.com/Rk9gD9
typedef char char_t; // Char type
typedef char* char_ptr; // Char pointer
typedef const char* char_const_ptr; // Char const pointer
IS_SAME( char, char ); // Obviously true
IS_SAME( char, float ); // Obviously false
// Testing char_t
IS_SAME( char, char_t ); // true: OK
IS_SAME( const char, char_t ); // false: OK
IS_SAME( char, const char_t ); // false: OK
IS_SAME( const char, const char_t ); // true: OK
// Testing char_ptr
IS_SAME( char*, char_ptr ); // true: OK
IS_SAME( const char*, char_ptr ); // false: OK
IS_SAME( char*, const char_ptr ); // false: OK
IS_SAME( const char*, const char_ptr ); // false: Why?
IS_SAME( char* const, char_ptr ); // false: OK
IS_SAME( char* const, const char_ptr ); // true: Why?
// Testing char_const_ptr
IS_SAME( char*, char_const_ptr ); // false: OK
IS_SAME( const char*, char_const_ptr ); // true: OK
IS_SAME( char* const, char_const_ptr ); // false: OK
I can correctly predict all cases, except the ones with is_same<const char*, const char_ptr> and is_same<char* const, const char_ptr> which are the opposite of what I expected them to be.
My understanding from this SO topic is that writing const before a typedef'ed pointer type is actually equivalent to writing const after the un-typedef'ed pointer type (which matches results from the above test). I just can't seem to relate to a good memory technique for reminding myself in the future when the const type qualifier should be written before or after the typedef'ed or untypedef'ed type.
I'll illustrate what's happening with the
typedefand the addedconstwith this code (that passes the static assertion):constapplies to the pointer - not thecharit's pointing at.constalways applies to what's left of it - unless there's nothing to the left, then it applies to what's right of it, but it's applied to the wholechar_ptras-if by doingchar_ptr const.