C ++中的两个'char*'铸件有什么区别
What is the difference between two 'char*' castings in c++
>我确实有一个"C"函数
find_register(char *name)
从"C++"例程调用。第一个提示是
find_register("%ebx")
它会导致警告
deprecated conversion from string constant to 'char*'
好的,我将其更正为
find_register(string("%ebx").c_str())
这会导致错误消息
"invalid conversion from 'const char*' to 'char*'
最后
find_register((char*)string("%ebx").c_str())
被接受,没有错误消息和警告。
我的问题:1./错误消息的可能原因是更改"const char*"的可能性保持开放状态。没关系,但在第一种情况下,不太复杂的版本允许相同的操作,将字符串常量转换为"char *"是一种合法但已弃用的转换。背后还有什么更深层次的原因吗?
2./有没有简单的方法可以做我想做的事?(完美的(对于编译器)代码对于程序员来说几乎是不可读的)
原因在于C++语言的原始根源,回到与 C 语言一定程度的向后兼容性被认为很重要的时代。
在 C 语言中,字符串文字尽管不可修改,但具有类型 char [N]
。因此,它们可以隐式转换为 C 中的类型 char *
。在C++字符串文本的类型为 const char[N]
。从形式上讲,const char[N]
不能隐式转换为char *
。但是由于上述C兼容性原因,原始C++规范(C++98)允许将字符串文字隐式转换为char *
。此例外仅适用于直接字符串文本,作为对字符串文本提供的一种特殊处理形式。
但最终 C 兼容性的问题变得不重要,这种特殊处理在 C++03 中被弃用。所以,这就是编译器告诉你的。在您的find_register("%ebx")
调用中,它同意将直接字符串文字转换为char *
,但警告您此转换已被弃用。在C++11中,这种隐含的皈依被完全取缔。
在所有其他上下文(不是直接字符串文本)中,禁止将const char [N]
或const char *
隐式转换为char *
,并且一直被禁止。这就是为什么你的
find_register(string("%ebx").c_str())`
变体没有编译的机会。
至于如何解决此限制...如果您确定find_register(char *name)
不会尝试更改name
指向的数据(并且您不能仅将find_register
的参数类型更改为const char *name
),则
find_register(const_cast<char *>("%ebx"))
是一个相当可接受的解决方案(附有适当的注释)。当然,如果find_register
是一个修改函数,那么你必须做一些类似的事情。
char reg[] = "%ebx";
find_register(reg);
函数 find_register(char*)
的原型指示它可能会更改参数,因为它只是一个传递的指针。您没有提到您是否拥有该函数的源代码,所以我假设您没有,否则最好更改该函数以接受char const *
,前提是它不会更改内容。
否则只需传递一个可修改的数组:
char arg[] = "%ebx";
find_register(arg);
写:
find_register((char*)string("%ebx").c_str())
很危险,如果函数确实修改了字符串怎么办,例如 strtok
?但是,如果您坚持至少尝试使用C++样式的铸造而不是C转换(在这种情况下find_register(const_cast<char*>("%ebx"))
)。
旁注:就我个人而言,我发现在可能的情况下避免使用 C 方式放置 const 更容易阅读。因此,当指针恒定时,与其写const char *
写char const *
和char * const
,即 const 总是向左走 - 它更一致。
如果你将字符串文字传递给find_register(char *name)
,那么函数原型应该是find_register(const char *name)
的,因为字符串文字是不可修改的。
通过这种转换,C++会很乐意让你搬起石头砸自己的脚并尝试修改name
,这给了我一个分段错误,如以下代码所示:
void modifyIllegally(char* name) {
name[0]='d';
}
int main() {
modifyIllegally("abc");
}
编辑:如果您不控制 C 程序的 API 并且确定它不会更改char*
,则可以使用编译器标志禁用此警告。对于 gcc,标志是 -Wno-write-strings
.
- 在 C++ 中,字符串 a= "hello" 和字符串 a=(char *) "hello"有什么区别?
- 在 c++ 中,char *p 和 const char * p 有什么区别?
- for(char&c : s) 和 for(char c : s)之间的区别?
- 当返回一系列字符或指针到char文字时的区别
- char*const和constchar*之间有什么区别?(重复-需要更多澄清)
- "char *"和"char * = new char[]"之间的C++区别
- 忽略内存消耗,使用“int”或“char”是否有区别
- char阵列[]和char *数组之间有什么区别
- 使用char*argv[]而不是char*argv[]有很大的原因/区别吗
- (char*)和char*之间有什么区别
- C++ 中 int* 和 char* 之间的区别
- 定义 char 和 int 时指针有什么区别
- 函数int get()和istream&get(char&c)有什么区别
- C ++中的两个'char*'铸件有什么区别
- C++ 中的 'char()' 和 'char' 有什么区别
- typedef char[4] A 和 typedef char (&A)[4] 有什么区别?
- 在 C++ 中存储字符串时,char* 和 char 有什么区别?
- char *和string的区别
- 我不能理解const char*和char*之间的区别
- char*和char arr[]的区别- c++ /C