0

I have a function that specifies a const parameter to indicate to the caller that it won't be modfied:

int func1(const char *some_string) 
{
    // Do something non-destructive with some_string
}

I pass a non-const variable as an argument to func1:

int func2(void)
{
    char *my_string = "my text";
    func1(my_string);
}

gcc reports:

warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]

What is the correct way to deal with this situation? Creating a const copy of my_string seems a bit much, but simply casting seems like burying the warning.

retrodev
  • 2,323
  • 6
  • 24
  • 48
  • 3
    It's not warning about the function call, it's warning about the initialisation of my_string. If you had const char *my_string = "my_test"; it wouldn't complain... – Joe Jun 08 '17 at 08:45
  • 4
    The problem cannot get reproduced with the code posted - the code is perfectly fine. I would suspect that you are accidentally compiling the code as C++. – Lundin Jun 08 '17 at 08:46
  • 3
    @Joe That's not correct. String literals are of type `char[]` in C, unlike C++. – Lundin Jun 08 '17 at 08:46
  • @Lundin, it's an inherited project using autotools. How can I determine if it was compiled for C++? – retrodev Jun 08 '17 at 08:52
  • @retrodev `#ifdef __cplusplus #error something #endif`` and your program won't compile any more if C++... – Aconcagua Jun 08 '17 at 09:01
  • If you don't even know which compiler you are using, this warning is the least of your problems... I don't know anything about autotools, sorry. – Lundin Jun 08 '17 at 09:01
  • What happens when you replace char *my_string with char my_string[]? – Malcolm McLean Jun 08 '17 at 09:33

3 Answers3

1

The issue you're having stems from your main function.

When you declare char *my_string = "my text";,you are creating a non-const pointer to a string literal. By design, string literals such as "my text" are immutable, and therefore const in the language. (In practice, the compilers usually put the string literals into a specific section of the executable which contains read-only memory, so attempting to modify the literal using the non-const pointer can lead to a segfault.)

By declaring a non-const pointer to the string literal, you end up with a pointer which you could use to modify the immutable string literal, which is considered undefined behavior in C.

See this question for more information.

The easiest way to solve this is to simply change char *my_string into const char *my_string.

Andrei Bârsan
  • 3,473
  • 2
  • 22
  • 46
  • 3
    This does not explain the warning. Even though string literals are guaranteed to be stored in read-only memory, their type is still a read/write one `char[]`. This is a well-known defect in the language, that was fixed in C++ but not in C. – Lundin Jun 08 '17 at 08:57
  • Good point! It seems that the reasoning behind the non-constness of string literals in C is a little fuzzy. (https://stackoverflow.com/questions/3075049/why-do-compilers-allow-string-literals-not-to-be-const) – Andrei Bârsan Jun 08 '17 at 09:44
  • 2
    Historical reasons. Some old crap systems (DOS for example) did allow you to write to string literals and many crappy programmers abused that. To be backwards-compatible with crap programs for crap systems, C kept the string literal type as `char[]`. While C++ soundly recognized all such arguments as nonsense and changed string literals to the correct type `const char[]`. – Lundin Jun 08 '17 at 09:56
0

You could use const char *my_string = "my text"; instead of char *my_string = "my text";

Yunbin Liu
  • 1,484
  • 2
  • 11
  • 20
0

The error comes because the project is compiled with -Wwrite-strings extra warning. This warning is not enabled by default by any common warning options, -Wall, -Wextra because it can make even strictly conforming C programs produce diagnostics messages.

Namely

char *foo = "bar";

is a strictly conforming C fragment as such, "bar" being a non-modifiable array of type char [4]. Using char * for the type is not the best practice though, and const char *foo should use instead if possible. The -Wwrite-strings makes this not-the-best practice visible. It is just meant as an aide to write better programs but it as such doesn't uncover the real problems.