The standard function strstr
is used to find the location of a sub-string in a string. Both the arguments of the function are of const char *
type, but the return type is char *
.
标准函数strstr用于查找字符串中子字符串的位置。函数的两个参数都是const char *类型,但是返回类型是char *。
I would like to know how a standard function is implemented violating the const-correctness.
我想知道一个标准函数是如何违背const-correct实现的。
7 个解决方案
#1
13
C allows pointing to memory with const or non-const pointers, regardless if the object was defined with the const qualifier or not.
C允许使用const或非const指针指向内存,无论对象是否使用const限定符定义。
6.5 Expressions
6.5表达式
- An object shall have its stored value accessed only by an lvalue expression that has one of the following types:
- 对象的存储值应仅由具有以下类型之一的lvalue表达式访问:
— a qualified version of a type compatible with the effective type of the object,
-与该对象的有效类型兼容的类型的合格版本,
The prototype of strstr in C is:
strstr在C中的原型为:
char *strstr(const char *s1, const char *s2);
The returned pointer, if valid, points to string s1. This can be achieved with a cast:
返回的指针(如果有效)指向字符串s1。这可以通过以下方法实现:
const char safe = 's' ;
char* careful = ( char* )&safe ;
The problem is modifying that memory.
问题是修改内存。
6.7.3 Type qualifiers
6.7.3类型限定符
- If an attempt is made to modify an object defined with a const-qualified type through use of an lvalue with non-const-qualified type, the behavior is undefined.
- 如果尝试通过使用具有非const限定类型的lvalue来修改定义为const限定类型的对象,则该行为未定义。
Since you created the string, you should know whether you can modify it or not, therefore you can accept the return value with a pointer to const, to avoid any problems:
既然你创建了这个字符串,你应该知道你是否可以修改它,所以你可以用一个指向const的指针来接受返回值,以避免任何问题:
const char* find = strstr( ... ) ;
#2
28
All the const char *
is telling you is that strstr
is not going to modify the string you pass into it.
所有const char *告诉你的是strstr不会修改你传入的字符串。
Whether you modify the returned string or not is up to you as it is your string!
是否修改返回的字符串取决于您,因为它是您的字符串!
In C++ this has been changed by overloading the method and having two versions, the const
input version has a const
output.
在c++中,由于重载了方法并有两个版本,const输入版本有一个const输出。
In C it doesn't have quite that level of safety built in for you and assumes you know yourself whether you should be modifying the returned string.
在C中,它没有那么高的安全性,假设你知道自己是否应该修改返回的字符串。
#3
13
According to ISO C++ 21.8(7) strstr
returns a const char*
or a char*
depending on if it gets a const char*
or a char*
.
根据ISO c++ 21.8(7), strstr返回const char*或char*,具体取决于它得到const char*还是char*。
const char* strstr(const char* s1, const char* s2); char* strstr( char* s1, const char* s2);
#4
5
It's done by specifying the signature, and leaving the implementation up to the compiler builders.
通过指定签名,并将实现留给编译器构建器来完成。
Note that returning a char*
which points to a const char[]
string is just dangerous, but not yet a violation of any rule. However, any attempt to write to that memory is still Undefined Behavior.
注意,返回指向const char[]字符串的char*是危险的,但还没有违反任何规则。然而,任何写入内存的尝试仍然是未定义的行为。
#5
4
The strstr
function dates back to an era before there was such a thing as a const
pointer. In cases were it would be legal for code to write to memory identified by the first pointer passed to strstr
, it would be legal for code to write to memory identified by the returned pointer, and in cases where the returned value would only be used in ways that were legal with a pointer to read-only memory (e.g. a string literal), one could legally pass such a pointer to strstr
.
strstr函数可以追溯到一个时代之前,它是一个const指针。例将是合法的代码写入内存被第一个指针传递给strstr,这将是合法的代码写入内存被返回的指针,和在这种情况下,返回的值只会被使用的方式与一个指针是合法的只读存储器(如字符串),一个可以合法strstr通过这样一个指针。
If a functionality similar to strstr
were being defined today, it might be implemented using two methods--one of which could accept any pointer and return a pointer which could not be written by the recipient, and one of which would only accept writable pointers but would return a pointer that the recipient could use as it saw fit. Because some code which used strstr
would need to pass read-only pointers, however, and because some code which used strstr
needed to be able to write to the pointers that it would yield when given writable pointers, it was necessary to have one set of pointer qualifications work both ways. The consequence is a set of pointer qualifications which are not really "safe" [since it may return a writable pointer to a read-only area of memory] and which will let code compile in some cases where it really "shouldn't", but which will allow code written before the days of const
pointers to continue working as intended.
如果一个功能类似于strstr今天被定义,它可能使用两种方法来实现,其中一个可以接受任何指针并返回一个指针不能写的收件人,和其中一个只接受可写指针但会返回一个指针,收件人可以使用,因为它认为合适的。但是,由于使用strstr的一些代码需要传递只读指针,并且由于使用strstr的一些代码需要能够对给定可写指针时产生的指针进行写入,因此有必要同时使用一组指针条件。结果是一组指针的资格,并不是真正的“安全”(因为它会返回一个可写指针指向一个只读区域的内存),这将让代码编译在某些情况下,它真的“不应该”,但这将使代码之前编写的常量指针继续工作。
#6
2
C++ provides two versions one that takes const arguments and ones that takes non-const.
c++提供了两个版本,一个采用const参数,另一个采用非const参数。
const char* strstr( const char* str, const char* target );
char* strstr( char* str, const char* target );
Since in C we can not overload, we are left with two unpleasant choices:
既然在C语言中我们不能超负荷,我们就会有两个不愉快的选择:
- Either we take the arguments as non-const but if our sources are indeed const then we need to perform an unpleasant cast to non-const.
- 要么我们认为这些论点不连贯,但如果我们的信息源确实混乱,那么我们就需要对不连贯的信息进行不愉快的处理。
- The second option is the one we have which is that we take the arguments as const but we return a non-const. We could return a const char* but then we could never modify the result.
- 第二种选择是我们有一个我们把参数当作常量但是我们返回一个非常量。我们可以返回一个const char*,但是我们不能修改结果。
#7
1
The return value is not the variable that you have passed to the function as parameter. This function returns a pointer to the first occurrence in haystack of any of the entire sequence of characters specified in needle, or a null pointer if the sequence is not present in haystack.
返回值不是作为参数传递给函数的变量。这个函数返回一个指向haystack中指定的所有字符序列的第一个事件的指针,或者如果haystack中没有这个序列,返回一个空指针。
#1
13
C allows pointing to memory with const or non-const pointers, regardless if the object was defined with the const qualifier or not.
C允许使用const或非const指针指向内存,无论对象是否使用const限定符定义。
6.5 Expressions
6.5表达式
- An object shall have its stored value accessed only by an lvalue expression that has one of the following types:
- 对象的存储值应仅由具有以下类型之一的lvalue表达式访问:
— a qualified version of a type compatible with the effective type of the object,
-与该对象的有效类型兼容的类型的合格版本,
The prototype of strstr in C is:
strstr在C中的原型为:
char *strstr(const char *s1, const char *s2);
The returned pointer, if valid, points to string s1. This can be achieved with a cast:
返回的指针(如果有效)指向字符串s1。这可以通过以下方法实现:
const char safe = 's' ;
char* careful = ( char* )&safe ;
The problem is modifying that memory.
问题是修改内存。
6.7.3 Type qualifiers
6.7.3类型限定符
- If an attempt is made to modify an object defined with a const-qualified type through use of an lvalue with non-const-qualified type, the behavior is undefined.
- 如果尝试通过使用具有非const限定类型的lvalue来修改定义为const限定类型的对象,则该行为未定义。
Since you created the string, you should know whether you can modify it or not, therefore you can accept the return value with a pointer to const, to avoid any problems:
既然你创建了这个字符串,你应该知道你是否可以修改它,所以你可以用一个指向const的指针来接受返回值,以避免任何问题:
const char* find = strstr( ... ) ;
#2
28
All the const char *
is telling you is that strstr
is not going to modify the string you pass into it.
所有const char *告诉你的是strstr不会修改你传入的字符串。
Whether you modify the returned string or not is up to you as it is your string!
是否修改返回的字符串取决于您,因为它是您的字符串!
In C++ this has been changed by overloading the method and having two versions, the const
input version has a const
output.
在c++中,由于重载了方法并有两个版本,const输入版本有一个const输出。
In C it doesn't have quite that level of safety built in for you and assumes you know yourself whether you should be modifying the returned string.
在C中,它没有那么高的安全性,假设你知道自己是否应该修改返回的字符串。
#3
13
According to ISO C++ 21.8(7) strstr
returns a const char*
or a char*
depending on if it gets a const char*
or a char*
.
根据ISO c++ 21.8(7), strstr返回const char*或char*,具体取决于它得到const char*还是char*。
const char* strstr(const char* s1, const char* s2); char* strstr( char* s1, const char* s2);
#4
5
It's done by specifying the signature, and leaving the implementation up to the compiler builders.
通过指定签名,并将实现留给编译器构建器来完成。
Note that returning a char*
which points to a const char[]
string is just dangerous, but not yet a violation of any rule. However, any attempt to write to that memory is still Undefined Behavior.
注意,返回指向const char[]字符串的char*是危险的,但还没有违反任何规则。然而,任何写入内存的尝试仍然是未定义的行为。
#5
4
The strstr
function dates back to an era before there was such a thing as a const
pointer. In cases were it would be legal for code to write to memory identified by the first pointer passed to strstr
, it would be legal for code to write to memory identified by the returned pointer, and in cases where the returned value would only be used in ways that were legal with a pointer to read-only memory (e.g. a string literal), one could legally pass such a pointer to strstr
.
strstr函数可以追溯到一个时代之前,它是一个const指针。例将是合法的代码写入内存被第一个指针传递给strstr,这将是合法的代码写入内存被返回的指针,和在这种情况下,返回的值只会被使用的方式与一个指针是合法的只读存储器(如字符串),一个可以合法strstr通过这样一个指针。
If a functionality similar to strstr
were being defined today, it might be implemented using two methods--one of which could accept any pointer and return a pointer which could not be written by the recipient, and one of which would only accept writable pointers but would return a pointer that the recipient could use as it saw fit. Because some code which used strstr
would need to pass read-only pointers, however, and because some code which used strstr
needed to be able to write to the pointers that it would yield when given writable pointers, it was necessary to have one set of pointer qualifications work both ways. The consequence is a set of pointer qualifications which are not really "safe" [since it may return a writable pointer to a read-only area of memory] and which will let code compile in some cases where it really "shouldn't", but which will allow code written before the days of const
pointers to continue working as intended.
如果一个功能类似于strstr今天被定义,它可能使用两种方法来实现,其中一个可以接受任何指针并返回一个指针不能写的收件人,和其中一个只接受可写指针但会返回一个指针,收件人可以使用,因为它认为合适的。但是,由于使用strstr的一些代码需要传递只读指针,并且由于使用strstr的一些代码需要能够对给定可写指针时产生的指针进行写入,因此有必要同时使用一组指针条件。结果是一组指针的资格,并不是真正的“安全”(因为它会返回一个可写指针指向一个只读区域的内存),这将让代码编译在某些情况下,它真的“不应该”,但这将使代码之前编写的常量指针继续工作。
#6
2
C++ provides two versions one that takes const arguments and ones that takes non-const.
c++提供了两个版本,一个采用const参数,另一个采用非const参数。
const char* strstr( const char* str, const char* target );
char* strstr( char* str, const char* target );
Since in C we can not overload, we are left with two unpleasant choices:
既然在C语言中我们不能超负荷,我们就会有两个不愉快的选择:
- Either we take the arguments as non-const but if our sources are indeed const then we need to perform an unpleasant cast to non-const.
- 要么我们认为这些论点不连贯,但如果我们的信息源确实混乱,那么我们就需要对不连贯的信息进行不愉快的处理。
- The second option is the one we have which is that we take the arguments as const but we return a non-const. We could return a const char* but then we could never modify the result.
- 第二种选择是我们有一个我们把参数当作常量但是我们返回一个非常量。我们可以返回一个const char*,但是我们不能修改结果。
#7
1
The return value is not the variable that you have passed to the function as parameter. This function returns a pointer to the first occurrence in haystack of any of the entire sequence of characters specified in needle, or a null pointer if the sequence is not present in haystack.
返回值不是作为参数传递给函数的变量。这个函数返回一个指向haystack中指定的所有字符序列的第一个事件的指针,或者如果haystack中没有这个序列,返回一个空指针。