typedef指针const限定符的隐式转换问题及类型匹配解析
我发现给typedef定义的指针类型添加const限定符后,无法隐式转换为未typedef的const指针类型。以下用代码示例说明:使用GCC 8.3.0编译以下代码会失败:
typedef char* char_ptr; void myFunc(const char_ptr param); void test() { const char str[] = "Hello, World!"; myFunc(str); }
报错信息:
错误:无法将‘const char*’隐式转换为‘char_ptr’(别名‘char*’)[-fpermissive]
myFunc(str);
我不需要解决方案,已知类型转换、修改函数声明等多种解决方法,只想理解报错原因,以及为何仅在typedef指针的const限定场景下出现该问题。
为明确编译器对类型一致性的判断,我整理了测试用例:
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
我能正确预测大多数测试结果,但is_same<const char*, const char_ptr>和is_same<char* const, const char_ptr>的结果与预期相反。
核心原因:typedef是类型别名而非文本替换
typedef的本质是给已有类型起别名,不是简单的文本替换。当你给typedef定义的指针类型加const时,const修饰的是整个别名代表的类型,而不是拆分后的指针指向的内容。
比如:
typedef char* char_ptr中,char_ptr是char*的别名。const char_ptr等价于char* const(指针本身是const,不能修改指针指向的地址),而不是const char*(指向const char的指针,不能通过指针修改指向的内容)。
测试用例结果解析
is_same<const char*, const char_ptr>为false:const char_ptr是char* const,和const char*是完全不同的类型:前者是“const指针”,后者是“指向const的指针”,类型不匹配。is_same<char* const, const char_ptr>为true:
如前面所说,const char_ptr就是char* const的别名,二者是同一个类型。
记忆方法
把typedef的类型当成一个不可拆分的“黑盒”:
- 如果typedef的是普通类型(比如
typedef char char_t),const char_t就是const char,符合直觉。 - 如果typedef的是指针类型(比如
typedef char* char_ptr),const char_ptr就是“const的这个指针类型”——也就是指针本身不可变,对应char* const。 - 若要表示“指向const内容的指针”,应该在typedef时就把const包含进去,比如
typedef const char* char_const_ptr,这样char_const_ptr才等价于const char*。
内容的提问来源于stack exchange,提问作者vdavid

