![](/img/trans.png)
[英]How to avoid deprecated conversion from string constant to 'char*' in C++
[英]C++ deprecated conversion from string constant to 'char*'
我有一個private char str[256];
的類private char str[256];
為此,我有一個顯式的構造函數:
explicit myClass(const char *func)
{
strcpy(str,func);
}
我稱之為:
myClass obj("example");
當我編譯這個時,我得到以下警告:
不推薦將字符串常量轉換為'char *'
為什么會這樣?
警告:
不推薦將字符串常量轉換為'char *'
是因為你在某處(不是在你發布的代碼中)做的事情是這樣的:
void foo(char* str);
foo("hello");
問題是您正在嘗試將字符串文字(類型為const char[]
)轉換為char*
。
你可以將const char[]
轉換為const char*
因為數組衰減到指針,但你正在做的是使一個可變的常量。
這種轉換可能允許C兼容性,只是給你提到的警告。
這是您遇到以下情況時看到的錯誤消息:
char* pointer_to_nonconst = "string literal";
為什么? 那么,C和C ++在字符串文字的類型上有所不同。 在C中,類型是char數組,在C ++中,它是char的常量數組。 在任何情況下,都不允許更改字符串文字的字符,因此C ++中的const實際上不是限制,而是更多類型安全的東西。 出於安全原因,如果沒有顯式強制轉換,通常無法從const char*
轉換為char*
。 但是為了向后兼容C,語言C ++仍然允許將字符串文字分配給char*
並提供有關不推薦使用此轉換的警告。
所以,在某個地方,你在程序中缺少一個或多個const
來保持const的正確性。 但是,您向我們展示的代碼不是問題,因為它不會執行此類不推薦的轉換。 警告必須來自其他地方。
作為答案否。 2由fnieto - Fernando Nieto清楚而正確地描述了這個警告是因為你正在做的代碼中的某個地方(不是你發布的代碼中):
void foo(char* str);
foo("hello");
但是,如果您希望保持代碼無警告,則只需對代碼進行相應更改:
void foo(char* str);
foo((char *)"hello");
也就是說,簡單地將string
常量強制轉換為(char *)
。
有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");
也可以使用數組代替指針,因為數組已經是常量指針。
事實上,字符串常量文字既不是const char *也不是char *而是char []。 它很奇怪,但在c ++規范中寫下來; 如果修改它,則行為未定義,因為編譯器可能將其存儲在代碼段中。
也許你可以試試這個:
void foo(const char* str)
{
// Do something
}
foo("Hello")
這個對我有用
我通過在代碼的開頭添加這個宏來解決這個問題。 或者在<iostream>
添加它,呵呵。
#define C_TEXT( text ) ((char*)std::string( text ).c_str())
我也遇到了同樣的問題。 我簡單的做法就是添加const char *而不是char *。 問題解決了。 正如其他人在上面提到的,這是一個兼容的錯誤。 C將字符串視為char數組,而C ++將它們視為const char數組。
為了它的價值,我發現這個簡單的包裝類有助於將C ++字符串轉換為char *
:
class StringWrapper {
std::vector<char> vec;
public:
StringWrapper(const std::string &str) : vec(str.begin(), str.end()) {
}
char *getChars() {
return &vec[0];
}
};
這個問題的原因(比使用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 gibberish↔英語轉換器將C
聲明轉換為易於理解的英語語句,反之亦然。 這是一個僅限C
工具,因此不支持C++
獨有的東西(如constexpr)。
下面說明了解決方案,將字符串分配給指向常量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';
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.