Reputation: 1967
NOTE: I know there are many questions that talked about that but I'm still a beginner and I couldn't understand the examples.
I got a function prototype that goes like this:
int someFunction(const char * sm);
Here, as you know, const char* means that this function can accept const or non-const pointer-to-char. I tried something like that in the function body:
someMemberVar = sm;
someMemberVar is just a pointer-to-char. The compiler gives me an error telling me: cannot convert from const char* to char*.
Here, I didn't pass a constant, so either sm or someMemberVar aren't constants. So, what constant the compiler is talking about?
Upvotes: 9
Views: 41713
Reputation: 111288
I'll try to put in simpler terms what others are saying:
The function someFunction
takes a read-only string (for simplicity's sake, though char *
could be used in umpteen other cases). Whether you pass in a readonly string to someFunction
or not, the parameter is treated as read-only by the code executing in the context of this function. Within this function therefore, the compiler will try to prevent you from writing to this string as much as possible. A non-const pointer is such an attempt to disregard the read-only tag to the string and the compiler, rightly and loudly informs you of such disregard for its type system ;)
What's the difference between: int someFunction(const char * sm) const{...} and this: int someFunction(const char * sm){...}
The first is a function which takes a readonly parameter. The second const
written after the closing parentheses is valid only for member functions. It not only takes a read-only parameter, but also gurantees to not alter the state of the object. This is typically referred to as design level const.
Upvotes: 13
Reputation: 38868
In a comment from one of the other answers you said:
const char * sm mean that I can pass a const or non-const, so why C++ converts it automatically? That doesn't make sense to me.
Between your original question and that comment I think you're misunderstanding how the compiler treats the types.
You're correct that a non-const char *
can be cast safely to a const char *
. However, your method is explicitly taking a const char *
. So, while you can pass a char *
into the function, the compiler simply automatically casts the argument when making the function call. The actual code in the function doesn't know if the original argument was const or not. The compiler has to go by the actual declaration of the variable you're using, not some previous variable that had the same value.
If you want to be able to treat non-const char *
variables differently (assigning them) then you'll need to define a function that takes non-const char *
variables.
Upvotes: 1
Reputation: 644
In your example sm is const char* so someFunction has a contract with it's caller that it will not modify the memory that sm points to.
But if you assign sm to someMemberVar and someMemberVar is not const char* you will then be able to modify the memory that sm points to via someMemberVar and the compiler doesn't allow you to do that.
Upvotes: 0
Reputation: 84239
const char*
is a pointer to constant char:
const char* ptr0; // ptr0 is mutable, *ptr0 is const
char* const ptr1; // ptr1 is const, *ptr1 is mutable
Upvotes: 5
Reputation:
const char * sm is a pointer to a constant character (or array). When you try to assign, someMemberVar, a pointer-to-char, you are trying to point it to a set of constant characters. This is the cause for error.
Upvotes: 0
Reputation: 67839
If you pass a non-const pointer to someFunction
, it is automatically converted to a const pointer. So you can't assign sm
to someMemberVar
because that would violate the constness of sm. You could declare someMemberVar
as a const char*
and your code would work, however, you could not modify what it pointed to.
Upvotes: 1
Reputation: 101665
It is not entirely clear from your question, and I suspect the text of the error that you give is actually wrong, and actually reads:
cannot convert from
const char*
tochar*
Since you say that
someMemberVar is just a pointer-to-char.
This makes sense. Keep in mind that const char*
is actually the same as char const*
- that is, it is a pointer to a const char, not a const pointer to char! And you cannot convert a pointer to T const
to a pointer to T
, because that breaks type safety. Consider:
const char* a = "abc";
char* b = a; // what you're trying to do
b[0] = 'x'; // if you could do it, you could change const data without casts
Upvotes: 11