views:

37803

answers:

12

So I'm working on an exceedingly large codebase, and recently upgraded to gcc 4.3, which now triggers this warning:

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

Obviously, the correct way to fix this is to find every declaration like char *s = "constant string"; or function call like void foo(char *s); foo("constant string"); and make them const char pointers. However, that would mean touching 564 files, minimum, which is not a task I wish to perform at this point in time. The problem right now is that I'm running with -werror, so I need some way to stifle these warnings. How can I do that?

A: 

Sounds like you answered your own question.

Obviously, the correct way to fix this is to find every declaration like char *s = "constant string"; or function call like void foo(char *s); foo("constant string"); and make them const char pointers.

The compiler doesn't care if it's convenient for you to do it now.

Nick Stinemates
He's not asking the compiler to "understand", he's looking for a way to suppress the noise so that he can fix the *real* warnings, i.e. the ones that may actually indicate logic problems. I'm sure he'll fix the other ones in time, but for now they're spam.
Graeme Perrow
Why was this post flagged (I think that's what the grey means?)? It may not be helpful, but it is not offensive.
Zifre
+27  A: 

I believe passing -Wno-write-strings to gcc will suppress this warning.

DGentry
Is it can be disabled on per file basic using pragmas.
Priyank Bolia
+25  A: 

Check out gcc's Diagnostic Pragma support, and the list of -W warning options. Looks like gcc doesn't have an equivalent to VC++'s #pragma warning(disable:NNNN) support which is very useful for cases like this.

Rob Walker
It's too bad I can't accept your answer as well; those are two really informative links. Thanks.
Josh Matthews
But you can upvote him...
Vinko Vrsalovic
It does actually: #pragma GCC diagnostic ignored "-Wwrite-strings"
bdonlan
+5  A: 

If it's an active code base, you might still want to upgrade the code base. Of course, performing the changes manually isn't feasible but I believe that this problem could be solved once and for all by one single sed command. I haven't tried it, though, so take the following with a grain of salt.

find . -exec sed -E -i .backup -n \
    -e 's/char\s*\*\s*(\w+)\s*= "/char const* \1 = "/g' {} \;

This might not find all places (even not considering function calls) but it would alleviate the problem and make it possible to perform the few remaining changes manually.

Konrad Rudolph
that does only solves declarations warnings and not function calls +1 for sed fu anyway :p
João Portela
A: 

The problem right now is that I'm running with -Werror

This is your real problem, IMO. You can try some automated ways of moving from (char *) to (const char *) but I would put money on them not just working. You will have to have a human involved for at least some of the work. For the short term, just ignore the warning (but IMO leave it on, or it'll never get fixed) and just remove the -Werror.

James Antill
The reason people use -Werror is so that warnings *do* get fixed. Otherwise they never get fixed.
Zan Lynx
The reason people use -Werror is because they've only worked on toy projects, or they are masochistic.Having your code fail to build because of a GCC update is a real problem when you have 100k+ LOC. Dito. someone adding junk like "-Wno-write-strings" to the build to get rid of the annoying warnings (like the highest rated comment in this post suggests).
James Antill
+1  A: 

Why don't you use the -Wno-deprecated option to ignore deprecated warning messages?

+3  A: 

I had a similar problem, I solved it like this:

#include <string.h>
extern void foo(char* m);

int main() {
    // warning: deprecated conversion from string constant to ‘char*’
    //foo("Hello");

    // no more warning
    char msg[] = "Hello";
    foo(msg);
}

Is this an appropriate way of solving this? I do not have access to foo to adapt it to accept 'const char*', although that would be a better solution (because foo does not change m).

BlackShift
-1 for copying memory around wasting the universe energy (or dead dinosaurs)
elcuco
@elcuco , what would you propose? I couldn't edit foo, and tried to find a solution that did not require suppression of the warning.In my case the latter was more a matter of exercise, but for the original poster it seemed important. As far as I can tell, my answer is the only one that would solve both my and the OP's conditions at the same time so it could be a valuable answer to someone.If you think my solution is not good enough, could you please provide an alternative? (That does not include editing foo or ignoring the warning.)
BlackShift
if we assume that foo is properly codded (which unfortunately does not seem to be the case for the code 'Josh Matthews' is talking about) this is the best solution. that's because if the function needs to actually change the string 'msg' passing it a constant string would break the code, right? but anyway this does not seem to answer the question because the errors are already in the old code not in the new, so he would need to change the old code anyway.
João Portela
A: 

You can also create a writable string from a string constant by calling strdup().

For instance, this code generates a warning:

putenv("DEBUG=1");

However, the following code does not (it makes a copy of the string on the heap before passing it to putenv): putenv(strdup("DEBUG=1"));

In this case (and perhaps in most others) turning off the warning is a bad idea -- it's there for a reason. The other alternative (making all strings writable by default) is potentially inefficient.

Listen to what the compiler is telling you!

BillAtHRST
And it also leaks the memory allocated for that writable string.
RBerteig
Yes it does -- that's on purpose. Not a problem with one-time (e.g., initialization) code, as above. Or, you can manage the memory yourself and release it when you're done with it.
BillAtHRST
+3  A: 

I can't use the compiler switch. So I have turned this:

char *setf = tigetstr("setf");

to this:

char *setf = tigetstr((char *)"setf");
vy32
+1 - you cannot change lvalue of applications, only rvalue. this proved to fix the real problem. other just work around some issues with the compiler.
elcuco
The thing that is really annoying is that tigetstr() should be prototyped with a (const char *), not a (char *)
vy32
A: 

"Test string" <- This is const string. So you can solve like this: char str[] = "Test string"; or const char* str = "Test string"; printf(str);

alexsid
A: 
shindow
A: 

I got the WARNING with this code snippet with GCC compiler 4.3:

// WHY the following COMPILER WARNING ???
// "deprecated conversion from string constant to char *"
char *const name = "dennis";

My answer is that the right side is "char *", but the left side is "char *const", and they don't agree.

Thus we are trying to enforce constantness in the pointer in the assignment.

danceguy
the right side is `char const *` or `const char *`, which are the same. the left side is not. expanding: `char const *` means that the characters are `const` and cannot be changed, `char * const` means that the pointer is constant and not the characters. if you want both to be constant you can type `char const * const name`
João Portela