我有一堂课 private char str[256];
为此,我有一个显式的构造函数:
explicit myClass(const char *func)
{
strcpy(str,func);
}
我称其为:
myClass obj("example");
当我对此进行编译时,会收到以下警告:
从字符串常量到'char *'的弃用转换
为什么会这样呢?
我有一堂课 private char str[256];
为此,我有一个显式的构造函数:
explicit myClass(const char *func)
{
strcpy(str,func);
}
我称其为:
myClass obj("example");
当我对此进行编译时,会收到以下警告:
从字符串常量到'char *'的弃用转换
为什么会这样呢?
Answers:
当您遇到以下情况时,这是一条错误消息:
char* pointer_to_nonconst = "string literal";
为什么?嗯,C和C ++在字符串文字的类型上有所不同。在C语言中,类型是char数组,在C ++中,它是char型常量数组。无论如何,都不允许您更改字符串文字的字符,因此C ++中的const并不是真正的限制,而更多的是类型安全性。从A转换const char*
到char*
一般也不是没有可能的明确的转换出于安全原因。但是为了向后兼容C语言,C ++语言仍然允许为a分配字符串文字,char*
并向您发出有关此转换已弃用的警告。
因此,在某些地方您缺少const
const正确性的程序中的一个或多个。但是您显示给我们的代码不是问题,因为它不执行这种不建议使用的转换。该警告一定来自其他地方。
const
从MyClass
构造函数中删除来重现OP代码的问题,然后可以通过添加后缀来解决该问题const
。
警告:
从字符串常量到'char *'的弃用转换
给出是因为您正在某处(不在发布的代码中)执行以下操作:
void foo(char* str);
foo("hello");
问题是您正在尝试将字符串文字(类型为const char[]
)转换为char*
。
您可以将转换为const char[]
,const char*
因为数组会衰减到指针,但是您正在做的是使可变变量成为常量。
出于C兼容性的考虑,这种转换可能是允许的,只是给您警告。
作为答案。2 by fnieto-Fernando Nieto清楚正确地描述了发出此警告的原因,因为您正在执行的代码中的某处(而不是您发布的代码中)如下:
void foo(char* str);
foo("hello");
但是,如果您也想使代码保持无警告状态,则只需对代码进行相应的更改:
void foo(char* str);
foo((char *)"hello");
也就是说,只需将string
常量转换为即可(char *)
。
void foo(char* str)
原样?我想我们不能modity str
中foo
无论如何,即使参数被写成非const。
有3个解决方案:
解决方案1:
const char *x = "foo bar";
解决方案2:
char *x = (char *)"foo bar";
解决方案3:
char* x = (char*) malloc(strlen("foo bar")+1); // +1 for the terminator
strcpy(x,"foo bar");
也可以使用数组代替指针,因为数组已经是常量指针。
strdup
。与您的代码不同,它将为终止的NUL字符分配空间,并且不会超出分配范围。
实际上,字符串常量文字既不是const char *也不是char *,而是char []。这很奇怪,但是写在c ++规范中;如果修改它,则行为是不确定的,因为编译器可能会将其存储在代码段中。
我通过在代码开头的某个位置添加此宏来解决此问题。或将其添加到中<iostream>
,呵呵。
#define C_TEXT( text ) ((char*)std::string( text ).c_str())
C_TEXT
对于函数调用(foo(C_TEXT("foo"));
)来说很好,但是如果将值存储在类似这样的变量中,则会对未定义的行为大声疾呼char *x = C_TEXT("foo");
- x
(除赋值外)任何使用都是未定义的行为,因为它所指向的内存已被释放。
出现此问题的原因(比char* str = "some string"
其他人更难以解决的问题-别人已经解释过了)是在使用时constexpr
。
constexpr char* str = "some string";
似乎它的行为类似于const char* str
,因此不会像以前那样发生警告,char*
而是表现为char* const str
。
常量指针和指向常量的指针。const char* str
和之间的区别char* const str
可以解释如下。
const char* str
:声明str为指向const char的指针。这意味着该指针指向的数据是恒定的。可以修改指针,但是任何试图修改数据的尝试都会引发编译错误。
str++ ;
:有效。我们正在修改指针,而不是指向的数据。*str = 'a';
:无效。我们正在尝试修改所指向的数据。char* const str
:声明str为指向char的const指针。这意味着该点现在是恒定的,但是所指向的数据也不是恒定的。指针不能被修改,但是我们可以使用指针来修改数据。
str++ ;
:无效。我们正在尝试修改指针变量,它是一个常量。*str = 'a';
:有效。我们正在尝试修改所指向的数据。在我们的情况下,这不会导致编译错误,但是会导致运行时错误,因为字符串很可能会进入已编译二进制文件的只读部分。如果我们已经动态分配了内存,则该语句很有意义。char* const str = new char[5];
。const char* const str
:声明str为指向const char的const指针。在这种情况下,我们既不能修改指针,也不能指向数据。
str++ ;
:无效。我们正在尝试修改指针变量,它是一个常量。*str = 'a';
:无效。我们正在尝试修改此指针指向的数据,该数据也是恒定的。就我而言,问题在于我期望constexpr char* str
表现为const char* str
,而不是char* const str
,因为在视觉上看起来更接近前者。
另外,为生成的警告与constexpr char* str = "some string"
稍有不同char* str = "some string"
。
constexpr char* str = "some string"
:ISO C++11 does not allow conversion from string literal to 'char *const'
char* str = "some string"
:ISO C++11 does not allow conversion from string literal to 'char *'
。您可以使用C乱码↔英文转换器将C
声明转换为易于理解的英文语句,反之亦然。这是C
唯一的工具,因此将不支持独占的东西(例如constexpr)C++
。
我也遇到同样的问题。我所做的只是添加const char *而不是char *。问题解决了。正如其他人在上面提到的,这是一个兼容的错误。C将字符串视为char数组,而C ++将其视为const char数组。
以下说明解决方案,将字符串分配给char常量数组的变量指针(字符串是char常量数组的常量指针-加上长度信息):
#include <iostream>
void Swap(const char * & left, const char * & right) {
const char *const temp = left;
left = right;
right = temp;
}
int main() {
const char * x = "Hello"; // These works because you are making a variable
const char * y = "World"; // pointer to a constant string
std::cout << "x = " << x << ", y = " << y << '\n';
Swap(x, y);
std::cout << "x = " << x << ", y = " << y << '\n';
}
strncpy(str, func, 255)
而不是strcpy(str, func)
更安全的副本。然后不要忘记在字符串的末尾添加“ \ 0”,因为strncpy不会添加它。