'char **' 和 'const char **'的兼容性问题
2008-07-19 14:00
441 查看
有时候必须非常专注的阅读ANSI C 标准才能找到某个问题的答案。一位销售工程师把下面的代码作为测试例子发给SUN的编译器小组。
提交代码的工程师想知道为什么会产生类似的警告,他认为,实参char *s 与形参 const char *p 应该是相容的,标准库中所有的字符串处理函数都是这样的。那么,为什么实参 char **argv 与形参 const char **P实际上不能相容呢?答案是肯定的,它们并不相容。现在我们回顾一下标准中有关简单赋值的部分,它位于ANSI C 第6.3.16.1节,描述了下列约束条件:
要使上述赋值形式合法,必须满足下列条件之一:
两个操作数都是指向有限定符或无限定符的相容类型的指针,左边指针所指向的类型必须具有右边指针
所指向类型的全部限定符。
正是这个条件,使得函数调用中实参char*能够与形参const char*匹配。它之所以合法,是因为在下面的代码中:
char *cp;
const char *cpp;
cpp = cp;
左操作数是一个指向有const限定符的char的指针;
右操作数是一个指向没有限定符的char的指针;
char类型和char类型是相容的,左操作数所指向的类型具有右操作数所指向类型的限定符(无), 再加上自身的限定符 const (注意反过来不能赋值)。
标准第6.3.16.1节没有说明char **实参与const char **形参是否相容。标准6.1.2.5节中讲述实例的部分声称:const float * 类型并不是一个有限定符的类型,它的类型是“指向一个具有const限定符的float类型的指针”,也就是说const限定符是修饰指针所指向的类型,而不是指针。类似地,const char **[/b]也是一个没有限定符的指针类型,它的类型是“指向有const限定符的char类型的指针的指针”。 由于char ** 和const char ** 都是没有限定符的指针类型,但它们所指向的类型不一样(前者指向char *,后者指向 const char *),因此它们是不相容的[/b]。因此类型为char **的实参和类型为 const char **的形参是不相容的,编译器会产生一条诊断信息。
备注:解释的有些牵强,目前记住结果就可以了[/i]
[/i]
[/i][/i]
#include<stdio.h> void foo( const char **P ) {} int main( int argc, char **argv ) { foo( argv ); return 0; } 在VC6.0下编译这段代码,编译器会发出警告:[b][b] [b]cannot convert parameter 1 from char ** to const char **[/b][/b][/b] |
要使上述赋值形式合法,必须满足下列条件之一:
两个操作数都是指向有限定符或无限定符的相容类型的指针,左边指针所指向的类型必须具有右边指针
所指向类型的全部限定符。
正是这个条件,使得函数调用中实参char*能够与形参const char*匹配。它之所以合法,是因为在下面的代码中:
char *cp;
const char *cpp;
cpp = cp;
左操作数是一个指向有const限定符的char的指针;
右操作数是一个指向没有限定符的char的指针;
char类型和char类型是相容的,左操作数所指向的类型具有右操作数所指向类型的限定符(无), 再加上自身的限定符 const (注意反过来不能赋值)。
标准第6.3.16.1节没有说明char **实参与const char **形参是否相容。标准6.1.2.5节中讲述实例的部分声称:const float * 类型并不是一个有限定符的类型,它的类型是“指向一个具有const限定符的float类型的指针”,也就是说const限定符是修饰指针所指向的类型,而不是指针。类似地,const char **[/b]也是一个没有限定符的指针类型,它的类型是“指向有const限定符的char类型的指针的指针”。 由于char ** 和const char ** 都是没有限定符的指针类型,但它们所指向的类型不一样(前者指向char *,后者指向 const char *),因此它们是不相容的[/b]。因此类型为char **的实参和类型为 const char **的形参是不相容的,编译器会产生一条诊断信息。
备注:解释的有些牵强,目前记住结果就可以了[/i]
[/i]
[/i][/i]
相关文章推荐
- 'char **' 和 'const char **'的兼容性问题
- 'LoadLibraryW' : cannot convert parameter 1 from 'const char *' to 'LPCWSTR' 解决方案
- 错误:将'const x'作为'x'的'this'实参时丢弃了类型限定问题解决
- string转Char*( error C2440: '=' : cannot convert from 'const char *' to 'char *')
- Oracle中的'&'符号问题
- vs2013 IntelliSense: "const char *" 类型的实参与 "LPCWSTR" 类型的形参不兼容
- ' or '1'='1'等漏洞问题
- paip. 'QObject::QObject(const QObject&)' is private问题的解决.
- 问题:SQL Server 2008用'sa'登录失败,启用'sa'登录的办法
-  与 兼容性问题
- GetWindowTextW(LPTSTR,int) const' :cannot convert parameter 1 from 'char[10]
- 类型转换 -- 使用Unicode下的cannot convert parameter 1 from 'CString' to 'const char *' 解决办法
- "const char*"类型的实参与LPCTSTR类型的形参不兼容
- 报错 error C2664: 'CreateWindowExA' : cannot convert parameter 2 from 'unsigned short [10]' to 'const char *'
- E2034 Cannot convert 'wchar_t *' to 'const char *'
- 'ppm upgrade failed: DBD::SQLite::db selectrow_array failed: database disk image is malformed' 问题的解决
- "Failed to install ScanTest2.apk on device '040398DD0A018005!" 问题解决
- 编码 -- char 1= '中' 2 byte, 中文string a="中" 3字节问题
- 'mvc:annotation-driven' must have no character or element问题
- // 写一个函数,实现将一个字符串中的'/t'替换成四个'*', '/t'个数不定。如char *p="ht/thdsf/t/ttt/tfds dfsw/t ew/t",替换后p="ht****hdsf********tt****fds dfsw****