简体   繁体   English

为什么不能用另一个指向const char的指针初始化一个指针?

[英]Why can't a pointer be initialized with another pointer to a const char?

Here's another 'reinventing-the-wheel' problem we were given in our Introduction to C++ classes: 这是我们在C ++类简介中得到的另一个“重塑方向”问题:

Write a function that returns the position of the first occurrence of a sequence of characters in a string, ie a variation of the strstr function. 编写一个函数,该函数返回字符串中字符序列首次出现的位置,即strstr函数的变体。

I started writing the function as follows: 我开始如下编写函数:

int strstr2(const char *text, const char *pattern) {
    int pos = 0;
    char *temp;
    temp = text;
}

I thought I'd remember the address of the first character of the string for future use within the function, but the compiler said: 我以为我会记住该函数的字符串的第一个字符的地址以供将来使用,但是编译器说:

A value of type "const char*" cannot be assigned to an entity of type "char*". 无法将类型“ const char *”的值分配给类型“ char *”的实体。

I know that one cannot change a constant once it has been initialized, but why am I not able to assign a pointer to a constant char to another non-constant pointer? 我知道一旦初始化就无法更改常量,但是为什么我不能将指向常量char的指针分配给另一个非常量指针呢?

I read several questions referring to pointers and constants, and it seems the bottom of the accepted answer to this post might answer my question, but I'm not a hundred percent sure, as the discussion is still at too advanced a level for me. 我读了一些有关指针和常量的问题,似乎这篇文章的公认答案的底部可能回答了我的问题,但是我不确定百分百,因为对我来说讨论仍然处于高级水平。

My second question is, what is the workaround? 我的第二个问题是,解决方法是什么? How can I define a pointer pointing at the beginning of the string? 如何定义一个指向字符串开头的指针?

Thanks. 谢谢。

This has to do with const-correctness . 这与const-correctness有关 const char *text means text is a pointer to a constant char . const char *text表示text是指向常量char的指针。 That means if you try to do something like 这意味着如果您尝试做类似的事情

*text = 'a'

The compiler will issue an error since you are trying to modify a const object. 由于您尝试修改const对象,因此编译器将发出错误。 If you could do 如果可以的话

char *temp;
temp = text;

then you could do 那你可以做

*temp = 'a'

and there would be no error, even though you just modified a const object. 即使您刚刚修改了const对象,也不会出错。 This is why C++ requires you to use const_cast if you actually want to cast away const (there are a few use cases for this but they are by far not what you normally want to do). 这就是为什么如果您确实想抛弃const C ++要求您使用const_cast (有一些用例,但到目前为止,它们并不是您通常想要做的)。


Danger, there be dragons below. 危险,下面有龙。 Be very, very careful if you decide to use const_cast 如果决定使用const_cast,请非常小心

Lets say you have to deal with an old API call that only takes a char* , but it guarantees it wont modify , then you could use something like 假设您必须处理一个仅使用char*的旧API调用, 但它保证不会进行修改 ,那么您可以使用类似

int wrap_api(const char *text)
{
    return api_call(const_cast<char*>(text));
}

and this will be "okay" since api_call guarantees it wont modify the string. 并且这将是“好的”,因为api_call保证不会修改字符串。 If on the other hand api_call could modify then this would only be legal if what text points to isn't actually const like 另一方面,如果api_call可以修改,则仅当text指向的内容实际上不是const时才合法

char foo[] = "test"
wrap_api(foo);

would be legal if foo gets modified but 如果foo被修改将是合法的,但是

const char foo* = "test"
wrap_api(foo);

would not be legal if foo gets modified and is undefined behavior. 如果foo被修改并且是未定义的行为,则将不合法。

If the assignment would be allowed, you would be able to legally write: 如果允许分配,您将可以合法地编写:

*temp = 'x'; // write to char* is legal in general

But that would be bad in this case because you'd be writing to a constant. 但这在这种情况下会很糟糕,因为您将要写入一个常量。

The standard could have said that the temp = text assignment is legal and the *text = 'x' is undefined behavior, but that wouldn't make sense because the only difference between T* and const T* is whether you can write to it. 该标准可以temp = text分配是合法的,而*text = 'x'是未定义的行为,但这没有任何意义,因为T*const T*之间的唯一区别是是否可以写入它。

So it is only logical that C++ disallows assigning a T* type the value of a const T* type to save you from later doing something bad, and instead forces you to use const char* temp; temp = text; 因此,C ++禁止为T*类型分配const T* T*类型的值是很合乎逻辑的,这样可以避免以后做一些不好的事情,而是强制您使用const char* temp; temp = text; const char* temp; temp = text; in this case. 在这种情况下。

This is a part of const-correctness type safety. 这是const-correctness类型安全性的一部分。 Since text is a pointer to const char , you can't modify the characters it points to through it. 由于text是指向const char的指针,因此您无法修改其指向的字符。 This is a good thing and a safety measure. 这是一件好事,也是一项安全措施。

However, the whole safety would be invalidated if it would be allowed to assign a pointer to non-const character to it! 但是,如果允许为其分配非常量字符指针,则整个安全性将失效! Because than you would modify the character through said pointer and bypass the safety! 因为比起您可以通过上述指针修改字符并绕过安全性!

Because of that, this assignment is not allowed. 因此,不允许进行此分配。 To fix it, mark your temp as pointer to const char as well: const char* temp . 要解决此问题,请将您的temp也标记为指向const char的指针: const char* temp

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM