Scene
Scene

Reputation: 507

Ambiguity with const keyword in C

I have some code:

int main() {
    const char *string1 = "foo";
    char *string2 = "bar";

    string1 = string2;

    return 0;
}

When I build it, no warnings are raised. However, with

int main() {
    const char *string1 = "foo";
    char *string2 = "bar";

    string2 = string1;

    return 0;
}

A warning is raised:

warning: assignment discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
     string2 = string1;
             ^

With my current basic knowledge of C, I would have thought that string1 would not be reassignable since it is const. To my surprise, it was the code in the first snippet that built with no warnings and the second code snippet the opposite.

Any explanations of what is going on? Thanks!

Upvotes: 2

Views: 112

Answers (2)

klutt
klutt

Reputation: 31316

That is perfectly ok to do. The (potential) problem here is that the strings you're pointing at are string literals, so modifying them would invoke undefined behavior.

What you're mixing it up with is probably this:

  • const char *str1 - str1 is a pointer to const char
  • char * const str2 - str2 is a const pointer to char
  • const char * const str3 - str3 is a const pointer to const char

str1 can be reassigned to point at something else, but since it is a pointer to const char it cannot be used as an l-value, so *str1 = <something> is forbidden. str2 on the other hand cannot be reassigned to point at something else, but it can be used as an l-value. With str3 you cannot do any of those.

Also, note that const char *str and char const *str are equivalent. To find out what a declaration does, or to find out how to declare something, use this site: https://cdecl.org/

Upvotes: 5

Asteroids With Wings
Asteroids With Wings

Reputation: 17454

I would have thought that string1 would not be reassignable since it is const.

But it isn't!

It's a non-const pointer, pointing to a const thing (specifically, const chars).

The only reason your code is troublesome, is that you should not implicitly convert a const char* to char*, for fairly obvious reasons — it would defeat the purpose of const-safety to just drop const on a pointee type whenever you liked! That's why you're getting a warning.

Going the other way around, to add constness, as in your first example, is fine.

tl;dr: it's not your assignment; it's what you're assigning.

Upvotes: 0

Related Questions