I've got this function:
I call to that function like this:Code:int lortu_word_MCR(char* synset);
And I get this error:Code:std::string str;
...
lortu_word_MCR(str.c_str());
invalid conversion from `const char*' to `char*'
Why?
Printable View
I've got this function:
I call to that function like this:Code:int lortu_word_MCR(char* synset);
And I get this error:Code:std::string str;
...
lortu_word_MCR(str.c_str());
invalid conversion from `const char*' to `char*'
Why?
Because converting from const something to something is invalid. :) You need to build a char array, copy the content of the string, pass it to the function and then delete the array.
Because the string::c_str() function is defined this way, that it returns a non-modifyable C-String.
The easiest solution is to change your function lortu_word_MCR to take an argument of type std::string&, if the function really modifies its argument, or of type const std::string& or const char* if it doesn't.
If that is not possible, you have create temporarily a char*, e.g. by using strdup function.
You've got at least 2 options:
1. change:to:Code:int lortu_word_MCR(char* synset);
2. change:Code:int lortu_word_MCR(const char* synset);
to:Code:lortu_word_MCR(str.c_str());
In case your function really needs to change the contents of the string, then you shouldn't use the above, but instead to make a copy of the string before and after the function call.Code:lortu_word_MCR(const_cast<char *>(str.c_str()));
Regards,
Bornish, the second option will not work. If the string object was initially created as a const string - in that case removing the const-ness leads to undefined behaviour. Regards.
Again, you're so wrong... it will probably work and it is not undefined behaviour... it's just that is defined by the programmer who wrote the bloody code!Quote:
Originally Posted by exterminator
It seems that you've never had to write code with "special" constrains like mixing modules for which you don't have sources, where processing speed was most important requirement. If you can't modify the prototype of the function and neither the declaration of the string, fastest way is to cast out the const... which isn't a programming error if you KNOW it's safe, and also COMMENT it properly.
But then again, it is only my oppinion, and I might've misunderstood the requirement.
Cheers,
:D Why do you think I am wrong? And why do you think I am wrong "again"? :D I cannot understand that. :confused:Quote:
Again, you're so wrong... it will probably work and it is not undefined behaviour... it's just that is defined by the programmer who wrote the bloody code!
It seems that you've never had to write code with "special" constrains like mixing modules for which you don't have sources, where processing speed was most important requirement. If you can't modify the prototype of the function and neither the declaration of the string, fastest way is to cast out the const... which isn't a programming error if you KNOW it's safe, and also COMMENT it properly.
But then again, it is only my oppinion, and I might've misunderstood the requirement.
Well, rules are rules... that is how the things are defined.. it has nothing to do with what I have done or what I am doing or what I would be doing as far as programming is concerned. And you should be least worried about that for me.
I haven't had the pleasure of working with those "special" constraints but I still know that what I have said is correct .. (because it's not my opinion... but Herb sutter's ;) and probably in the standards as well)... I just wish if you had really asked me why I said that instead of quoting me "wrong".
You opinion isn't very helpful for the OP (and many viewers) in that case - they would be sitting infront of a crashed program wondering about the reason if they accept your suggestion... debugging...
You possibly have misunderstood me this time as well like you did ;) when you talked of polymorphism with static members of your class. Well, that's all I have to say. Take care. Best regards :).
If you can't change the prototype ( aka don't have the source-code ) how would you KNOW that it is safe to cast away constness ? ( Allright there could be a comment in the header saying "this is non const but just for fun". )Quote:
Originally Posted by Bornish
Kurt
const_cast can be used with any pointer to const-declared-objects or other objects.
And, it leads to undefined behavior, if, and only if, the pointer is effectively used to modify a const-object.
As Bornish said, some third-party functions don't use const correctly (or don't use const at all), so there are many functions that don't modify at all the object, but are declared as using a pointer to non-const.
In that case, it is perfectly valid, and does not lead to undefined behavior, to use const_cast (that is the purpose of const_cast).
However, note that const_cast must only be used in the case, the new pointer is not used to modify the object, or if we know that the original object was not declared with a const qualifier.
Quote:
Originally Posted by ISO C++
Thus:
But:Code:void Modify(const int *px)
{
const_cast<int*>(px)=42;
}
int main()
{
const int x;
int y;
Modify(&x);// undefined behaviour
Modify(&y);
return 0;
}
Bornish described this valid construct.Code:#include <iostream>
std::size_t ConstIncorrectStrlen(char* str)
{
char* p=str;
while(*p!='\0') ++p;
return p-str;
}
int main()
{
const char* str="hello world!";
std::cout<<ConstIncorrectStrlen(const_cast<char*>(str)); // Valid
}
That type of construct is uncommon in well written projects that don't use any third-party librairies, but can still be used:
For example, when overloading an accessor to a container (for example operator[]):
"const T&operator[](size_type) const" can be implemented in term of "T&operator[](size_type)".
It is useful if the code is complex, because it avoids having to maintain twice the same piece of code.
Okay, I apologize.. :blush: I had overlooked this statement of his.. which is what I was trying to refer to:
Quote:
Originally Posted by Bornish
I am not quite sure about this. You cannot modify the non-const object through the pointer or reference to the const object of the same type, pointing to it (non-const object) but you can surely modify the object through the pointer or reference got after the const_cast<> over that pointer or reference to make it mean as a pointer or reference to an object (now non-const since we cast away the const) pointing to the original non-const object got from casting away the pointer or reference to the const object initially pointing to it. So I am not sure if your first example with the modify function is correct. Here is an example from the same section of the standard that suffices what I said...Quote:
Originally Posted by Superkoko
The part in italics is what I am referring to. The const-qualified access path cannot be used to modify a non-const declared object but a non-const access path (got from a const_cast of a const-qualified access path) can surely be used to do that. Regards.Code:const int ci = 3; // cvqualified (initialized as required)
ci = 4; // illformed:attempt to modify const
int i = 2; // not cvqualified
const int* cip; // pointer to const int
cip = &i; // okay: cvqualified access path to unqualified
*cip = 4; // illformed: attempt to modify through ptr to const
int* ip;
ip = const_cast<int*>(cip); // cast needed to convert const int* to int*
*ip = 4; // defined: *ip points to i, a nonconst object
const int* ciq = new const int (3); // initialized as required
int* iq = const_cast<int*>(ciq); // cast required
*iq = 4; // undefined: modifies a const object
True, but the question remains: How do you know that the passed object is under no circumstances modified.Quote:
Originally Posted by SuperKoko
So I certainly would never recommend using const_cast in any mission-critical software. Don't think it is easy to test if it works or not, as the function that is called may store a non-const static pointer to the passed object and modify it much later. You never know.
- You have access to the source code (in which case the question arises, why you don't correct the interface)
- The function is in fact so simple that it would illogical to modify the passed object (in which case the arises, why you do not write it yourself instead of using a buggy library)
treuss : the third-party library may be quite complex but well documented.
In that case, the documentation would say if the data is modified or not.
How about using "&str[0]" instead of "const_cast<char *>(str.c_str())"?
&str[0] does not guarantee that the string is null-terminated. Depending on the implementation of std::string it might not be.Quote:
Originally Posted by googler