You are not logged in.

#1 2018-06-19 09:11:37

Chef_Keeper
Member
Registered: 2015-02-27
Posts: 18

C/C++ warning: deprecated conversion from string constant to ‘char*’

Hi,

We recently decided to use more warning flags for our project we got a recuring warning that came up :
"deprecated conversion from string constant to ‘char*’"

Now I'd really like to fix this in our code base, but there are at least 500 references of this warning, so I was thinking if it would be possible to use some kind of regexp magic to handle this ?

For example this code :

#include <stdio.h>

void    func(char *str)
{
  printf(str);
}

int main()
{
  func("WARNINGSSSSSSSSSSS");
  return (0);
}

produces :

g++ -W -Wall -Wwrite-strings main.c
main.c: In function ‘int main()’:
main.c:10:28: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
   func("WARNINGSSSSSSSSSSS");

To fix this we should add a const before char* at the func definition, in real life we should also add it to the declaration in headers...

Offline

#2 2018-06-19 10:14:26

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,523
Website

Re: C/C++ warning: deprecated conversion from string constant to ‘char*’

Chef_Keeper wrote:

I was thinking if it would be possible to use some kind of regexp magic to handle this ?

There is no magic, as in a one-size fits all command that will make your computer do your thinking for you.  But there are some simple sed commands that would most likely fix most of the incidences.  Test and revise on your code:

sed -n '/(.*char \*.*)$/p' src/*.c

If all the lines in that output should indeed be changed, then make the change:

sed -i '/(.*char \*.*)$/s/char \*/const char \*/g' src/*.c

If not all the lines in the first output should be changed, then revise the regex as needed until you get just the lines you want.

One thing to be cautious of, as is this will expand any current 'const char *' to 'const const char *'.  While I think that'd be harmless in the end, it'd look pretty silly in the code.

But also note this is a rather ill-defined problem.  Do you really want to change every char * in function arguments to be const?  Do you never modify the content of any char * passed to a function?

Personally, I'd take the more pragmatic approach: get everyone who writes code to be more explicit about argument types in the future, but for now, accept a warning as a warning.  Also note that the 'const' keyword in a function declaration really doesn't do nearly as much as many people think - it's mostly a hint to those that would call the function.  The function definition can't change the underlying data.

Last edited by Trilby (2018-06-19 10:22:26)


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#3 2018-06-19 12:39:49

Chef_Keeper
Member
Registered: 2015-02-27
Posts: 18

Re: C/C++ warning: deprecated conversion from string constant to ‘char*’

Trilby wrote:

Do you really want to change every char * in function arguments to be const?  Do you never modify the content of any char * passed to a function?

No that's the problem I want to changes those who got the wanings, but I think it's impossible ?

Offline

#4 2018-06-19 13:18:45

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,523
Website

Re: C/C++ warning: deprecated conversion from string constant to ‘char*’

Nothing is impossible.  But it may not be practical.  However, far far more importantly than this, the subset of functions that give that warning are not the right subset to change.

The 'const' in the function argument is a promise to the caller of the function that the content of the memory pointed to will not be changed.  Whether or not this const qualifier should be there depends entirely on the content of the function and nothing else.  But whether or not the compiler gives that warning has nothing to do with whether the const qualifier aligns with the content of the function, but rather it's all about the context of the call to the function.  This should most definitely not determine whether or not you add a const qualfier to the function declaration.

So it sounds like you are looking for a shortcut to silence the warning without actually dealing with what it's warning you about.  There are two simple strategies for that, remove that warning flag (if you are not planning on fixing it anways) or just `2>/dev/null` (worse, of course, but it has the same effect as just changing those functions for which the warning is emitted).

An example:

void func1(char *);
void func2(char *);

int main() {
   char s1[8] = "Hello";
   char *s2 = "World";
   func1(s1);
   func2(s2);
   return 0;
}

By your current logic, func2 should be modified to add a const qualifier, but func1 should not.  But in this code we have no idea what func1 and func2 actually do.  Whether the const qualifier should be there depends only on what those functions themselves do, not how they are called.  So there is a good chance that func1 should also have a const qualifier, but there'd be no warning from this code telling you to add it.  Even more dangerous, though, would be if func2 was right to not have the const qualifier because it modifies the memory pointed to by it's argument.  In this case, you'd see the warning and incorrectly add a const qualifier to the func2 definition/prototype.  This would prevent the compiler warnings you currently see, but it would either result in a different warning (hopefully) or it could just result in a binary that will segfault when run.

Last edited by Trilby (2018-06-19 13:31:16)


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#5 2018-06-20 12:55:46

Chef_Keeper
Member
Registered: 2015-02-27
Posts: 18

Re: C/C++ warning: deprecated conversion from string constant to ‘char*’

In your example I would rather treat func2 then treat nothing, I know it's not perfect but the purpose is to get to it step by step.

I'd really like to find some fast way to treat all the warnings with some regexp but I don't see how I could create such regexp : looking for all the warnings g++ gives and not directly correct that line but to search the line where this func is defined (because g++ warns on func call obviously).



Trilby wrote:

This would prevent the compiler warnings you currently see, but it would either result in a different warning (hopefully) or it could just result in a binary that will segfault when run.

Using const in a case you shouldn't will generate an error so I think it's pretty safe.

Offline

#6 2018-06-20 17:58:35

dmerej
Member
From: Paris
Registered: 2016-04-09
Posts: 101
Website

Re: C/C++ warning: deprecated conversion from string constant to ‘char*’

We had this kind of problem too.

We solved it with the help of CI (you do use continuous integration, right?)

First, go ahead and fix the code until no warnings are left. (I'm with Trilby on this, you should do it "by hand" and not try to automate this)

Second, tweak the compilation flags so that this warning results in a compilation failure. (If you feel like it you may also use  -WError but it this case, make sure the flag is not on by default or package maintainers will hate you ...)

By the way, you can also by-pass the warning using #pragma comments, but as always, only do this if you know what you're doing.

Hope this helps!


Responsible Coder, Python Fan, Rust enthusiast

Offline

#7 2018-06-20 22:15:02

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,523
Website

Re: C/C++ warning: deprecated conversion from string constant to ‘char*’

Chef_Keeper wrote:

In your example I would rather treat func2 then treat nothing

Why?  You'd just be artificially silencing a warning rather than addressing the underlying problem in the code.  What would be the point?  If you don't want to be pedantic about code correctness just disable that warning - no real harm will be done.  But if you do want to be pedantic about code correctness, then fix the code, don't just brush the warnings under the rug.

Compiler warnings are informative, and you want to decrease the informational value of that warning without addressing the message it is trying to give you.

Last edited by Trilby (2018-06-20 22:15:57)


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#8 2018-07-02 20:25:03

vedalken
Member
Registered: 2018-07-02
Posts: 1

Re: C/C++ warning: deprecated conversion from string constant to ‘char*’

Chef_Keeper wrote:

We recently decided to use more warning flags for our project we got a recuring warning that came up :
"deprecated conversion from string constant to ‘char*’"

That is unfortunate from development point of view. Generally most default warnings are used as warnings with carefully thought reason and should not be neglected in any way. For this case compiler says standard string class does not have conversion constructor allowing implicit conversion from string type to pointer to a character. What that really means?
Every class may allow specific implicit conversions (or coercion) between different types. This specific methods helps developers write code with minimal or unnecessary explicit conversions. For example (I use c++ code but it does not matter):

#include <iostream>

void divide(double a_value, int a_divide)
{
    std::cout << "foo value: " << a_value / a_divide << std::endl;
}

int main()
{
    int a = 5;
    divide(a, 2);

    return 0;
}

The program calls method divide with first argument as integer. Compiler known how to convert to floating point and does right that by implicit conversion to type double. The method prints floating point result event though both arguments are integers.

Now returning back to your example. The example code is typical example of bad coding style. That is not because of the compiler warning but because of the method "privileges". The method takes l-value type argument that is not modified within function call. Then the method can be declared as

void func(const char* str)
{
    printf(str);
}

As a advice for coding in C++ do not uses C system headers, instead use C++. Otherwise use C-compiler (gcc) in you example.

It seems you may have tedious work to fix the code in you project.

Offline

Board footer

Powered by FluxBB