C++已弃用从字符串常量到“char*”的转换

发布于 2024-08-07 00:42:52 字数 308 浏览 17 评论 0原文

我有一个带有私有 char str[256]; 的类

,并且我有一个显式构造函数:

explicit myClass(char *func)
{
    strcpy(str,func);
}

我将其称为:

myClass obj("example");

当我编译它时,我收到以下警告:

已弃用从字符串常量到“char*”的转换

为什么会发生这种情况?

I have a class with a private char str[256];

and for it I have an explicit constructor:

explicit myClass(char *func)
{
    strcpy(str,func);
}

I call it as:

myClass obj("example");

When I compile this I get the following warning:

deprecated conversion from string constant to 'char*'

Why is this happening?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

妳是的陽光 2024-08-14 00:42:52

当您遇到如下情况时,您会看到此错误消息:

char* pointer_to_nonconst = "string literal";

为什么? C 和 C++ 的不同之处在于字符串文字的类型。在 C 中,类型是 char 数组,在 C++ 中,它是 char 常量数组。无论如何,您都不允许更改字符串文字的字符,因此 C++ 中的 const 并不是真正的限制,而更多的是类型安全的东西。出于安全原因,如果没有显式强制转换,通常不可能从 const char*char* 的转换。但为了与 C 向后兼容,C++ 语言仍然允许将字符串文字分配给 char* 并为您提供有关此转换已弃用的警告。

因此,为了保证 const 的正确性,您的程序中某处缺少一个或多个 const。但您向我们展示的代码不是问题,因为它不执行这种已弃用的转换。该警告一定来自其他地方。

This is an error message you see whenever you have a situation like the following:

char* pointer_to_nonconst = "string literal";

Why? Well, C and C++ differ in the type of the string literal. In C the type is array of char and in C++ it is constant array of char. In any case, you are not allowed to change the characters of the string literal, so the const in C++ is not really a restriction but more of a type safety thing. A conversion from const char* to char* is generally not possible without an explicit cast for safety reasons. But for backwards compatibility with C the language C++ still allows assigning a string literal to a char* and gives you a warning about this conversion being deprecated.

So, somewhere you are missing one or more consts in your program for const correctness. But the code you showed to us is not the problem as it does not do this kind of deprecated conversion. The warning must have come from some other place.

半山落雨半山空 2024-08-14 00:42:52

警告:

已弃用从字符串常量到“char*”的转换

因为您正在某处(不在您发布的代码中)执行类似以下操作:

void foo(char* str);
foo("hello");

问题是您正在尝试转换字符串文字(类型为 const char[]) 到 char*

您可以将 const char[] 转换为 const char* 因为数组会衰减到指针,但您所做的是将可变变量设为常量。

这种转换可能是为了 C 兼容性而允许的,并且只会向您提供提到的警告。

The warning:

deprecated conversion from string constant to 'char*'

is given because you are doing somewhere (not in the code you posted) something like:

void foo(char* str);
foo("hello");

The problem is that you are trying to convert a string literal (with type const char[]) to char*.

You can convert a const char[] to const char* because the array decays to the pointer, but what you are doing is making a mutable a constant.

This conversion is probably allowed for C compatibility and just gives you the warning mentioned.

夜无邪 2024-08-14 00:42:52

作为答案是否定的。 2 by fnieto - Fernando Nieto 清楚而正确地描述了发出此警告的原因是您在代码中的某个位置(而不是在您发布的代码中)执行了类似以下操作:

void foo(char* str);
foo("hello");

但是,如果您想让代码保持无警告然后只需在代码中进行相应的更改:

void foo(char* str);
foo((char *)"hello");

即将 string 常量转换为 (char *)

As answer no. 2 by fnieto - Fernando Nieto clearly and correctly describes that this warning is given because somewhere in your code you are doing (not in the code you posted) something like:

void foo(char* str);
foo("hello");

However, if you want to keep your code warning-free as well then just make respective change in your code:

void foo(char* str);
foo((char *)"hello");

That is, simply cast the string constant to (char *).

明明#如月 2024-08-14 00:42:52

有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");

也可以使用数组代替指针,因为数组已经是常量指针。

更新:请参阅有关解决方案 3 的安全问题的评论。

There are 3 solutions:

Solution 1:

const char *x = "foo bar";

Solution 2:

char *x = (char *)"foo bar";

Solution 3:

char* x = (char*) malloc(strlen("foo bar")+1); // +1 for the terminator
strcpy(x,"foo bar");

Arrays also can be used instead of pointers because an array is already a constant pointer.

Update: See the comments for security concerns regarding solution 3.

素食主义者 2024-08-14 00:42:52

出现此问题的原因(比 char* str = "some string" 的问题更难检测 - 其他人已对此进行了解释)是当您使用 constexpr 时。

constexpr char* str = "some string";

它的行为似乎与 const char* str 类似,因此不会引起警告,因为它发生在 char* 之前,但它的行为与 char* const str

详细信息

常量指针,以及指向常量的指针。 const char* strchar* const str 之间的区别> 可以解释如下。

  1. const char* str :声明 str 为指向 const char 的指针。这意味着该指针指向的数据是恒定的。可以修改指针,但任何修改数据的尝试都会引发编译错误。
    1. str++ ;有效。我们正在修改指针,而不是所指向的数据。
    2. *str = 'a';无效。我们正在尝试修改所指向的数据。
  2. char* const str :声明 str 为指向 char 的 const 指针。这意味着该点现在是恒定的,但所指向的数据也不是恒定的。指针不能被修改,但是我们可以使用指针修改数据。
    1. str++ ;无效。我们正在尝试修改指针变量,它是一个常量。
    2. *str = 'a';有效。我们正在尝试修改所指向的数据。在我们的例子中,这不会导致编译错误,但会导致运行时错误,因为该字符串很可能会进入已编译二进制文件的只读部分。如果我们有动态分配的内存,那么这个语句就有意义,例如。 char* const str = new char[5];
  3. const char* const str :将 str 声明为指向 const char 的 const 指针。在这种情况下,我们既不能修改指针,也不能修改所指向的数据。
    1. str++ ;无效。我们正在尝试修改指针变量,它是一个常量。
    2. *str = 'a';无效。我们正在尝试修改此指针所指向的数据,该数据也是常量。

就我而言,问题是我期望 constexpr char* str 表现得像 const char* str,而不是 char* const str,因为从视觉上看它似乎更接近前者。

此外,为 constexpr char* str = "some string" 生成的警告与 char* str = "some string" 略有不同。

  1. constexpr char* str = "some string" 的编译器警告:ISO C++11 不允许从字符串文字转换为 'char *const'
  2. 的编译器警告>char* str = "some string"ISO C++11 不允许从字符串文字转换为“char *”

提示

您可以使用 C 乱码 ↔ 英语转换器C 声明转换为易于理解的英语语句,并且反之亦然。这是一个仅限 C 的工具,因此不支持 C++ 独有的东西(如 constexpr)。

A reason for this problem (which is even harder to detect than the issue with char* str = "some string" - which others have explained) is when you are using constexpr.

constexpr char* str = "some string";

It seems that it would behave similar to const char* str, and so would not cause a warning, as it occurs before char*, but it instead behaves as char* const str.

Details

Constant pointer, and pointer to a constant. The difference between const char* str, and char* const str can be explained as follows.

  1. const char* str : Declare str to be a pointer to a const char. This means that the data to which this pointer is pointing to it constant. The pointer can be modified, but any attempt to modify the data would throw a compilation error.
    1. str++ ; : VALID. We are modifying the pointer, and not the data being pointed to.
    2. *str = 'a'; : INVALID. We are trying to modify the data being pointed to.
  2. char* const str : Declare str to be a const pointer to char. This means that point is now constant, but the data being pointed too is not. The pointer cannot be modified but we can modify the data using the pointer.
    1. str++ ; : INVALID. We are trying to modify the pointer variable, which is a constant.
    2. *str = 'a'; : VALID. We are trying to modify the data being pointed to. In our case this will not cause a compilation error, but will cause a runtime error, as the string will most probably will go into a read only section of the compiled binary. This statement would make sense if we had dynamically allocated memory, eg. char* const str = new char[5];.
  3. const char* const str : Declare str to be a const pointer to a const char. In this case we can neither modify the pointer, nor the data being pointed to.
    1. str++ ; : INVALID. We are trying to modify the pointer variable, which is a constant.
    2. *str = 'a'; : INVALID. We are trying to modify the data pointed by this pointer, which is also constant.

In my case the issue was that I was expecting constexpr char* str to behave as const char* str, and not char* const str, since visually it seems closer to the former.

Also, the warning generated for constexpr char* str = "some string" is slightly different from char* str = "some string".

  1. Compiler warning for constexpr char* str = "some string": ISO C++11 does not allow conversion from string literal to 'char *const'
  2. Compiler warning for char* str = "some string": ISO C++11 does not allow conversion from string literal to 'char *'.

Tip

You can use C gibberish ↔ English converter to convert C declarations to easily understandable English statements, and vice versa. This is a C only tool, and thus wont support things (like constexpr) which are exclusive to C++.

浅暮の光 2024-08-14 00:42:52

事实上,字符串常量既不是 const char * 也不是 char*,而是 char[]。这很奇怪,但写在 C++ 规范中;如果修改它,则行为是未定义的,因为编译器可能会将其存储在代码段中。

In fact a string constant literal is neither a const char * nor a char* but a char[]. Its quite strange but written down in the c++ specifications; If you modify it the behavior is undefined because the compiler may store it in the code segment.

惯饮孤独 2024-08-14 00:42:52

也许你可以试试这个:

void foo(const char* str) 
{
    // Do something
}

foo("Hello")

它对我有用

Maybe you can try this:

void foo(const char* str) 
{
    // Do something
}

foo("Hello")

It works for me

攀登最高峰 2024-08-14 00:42:52

我通过在代码开头的某个位置添加这个宏来解决这个问题。或者在中添加,呵呵。

 #define C_TEXT( text ) ((char*)std::string( text ).c_str())

I solve this problem by adding this macro in the beginning of the code, somewhere. Or add it in <iostream>, hehe.

 #define C_TEXT( text ) ((char*)std::string( text ).c_str())
柏林苍穹下 2024-08-14 00:42:52

我也遇到了同样的问题。我所做的只是添加 const char* 而不是 char*。问题解决了。正如其他人上面提到的,这是一个兼容错误。 C 将字符串视为 char 数组,而 C++ 将字符串视为 const char 数组。

I also got the same problem. And what I simple did is just adding const char* instead of char*. And the problem solved. As others have mentioned above it is a compatible error. C treats strings as char arrays while C++ treat them as const char arrays.

此岸叶落 2024-08-14 00:42:52

就其价值而言,我发现这个简单的包装类有助于将 C++ 字符串转换为 char *

class StringWrapper {
    std::vector<char> vec;
public:
    StringWrapper(const std::string &str) : vec(str.begin(), str.end()) {
    }

    char *getChars() {
        return &vec[0];
    }
};

For what its worth, I find this simple wrapper class to be helpful for converting C++ strings to char *:

class StringWrapper {
    std::vector<char> vec;
public:
    StringWrapper(const std::string &str) : vec(str.begin(), str.end()) {
    }

    char *getChars() {
        return &vec[0];
    }
};
飘逸的'云 2024-08-14 00:42:52

下面说明了解决方案,将字符串分配给指向 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';
}

The following illustrates the solution, assign your string to a variable pointer to a constant array of char (a string is a constant pointer to a constant array of char - plus length info):

#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';
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文