17

Possible Duplicate:
How to get rid of deprecated conversion from string constant to ‘char*’ warnings in GCC?

I use following function from library which i cannot change:

HRESULT DynamicTag(char * pDesc, int * const pTag ); 

I use it as follows. I have created the object of the class provided by the library that implements the above function.

int tag =0;
g_pCallback->DynamicTag("MyLogger", &tag);

I am getting following warning:

warning: deprecated conversion from string constant to 'char*'

What is the best way of getting rid of above warning? I don't want to allocate memory dynamically.

Info: I am using Vxworks6.8 compiler

Community
  • 1
  • 1
venkysmarty
  • 11,099
  • 25
  • 101
  • 184

3 Answers3

17

Dealing with unknown library

When passing literals and not other const string, and you are not sure if the library is modifiying the string, is easy to create a stack allocated temporary copy of the literal in C++ (inspired by How to get rid of `deprecated conversion from string constant to ‘char*’` warnings in GCC?):

char strMyLogger[]="MyLogger";
g_pCallback->DynamicTag(strMyLogger, &tag);

Use explicit cast to work around a weak library prototype

On most compilers explicit conversions avoid warnings, like:

 g_pCallback->DynamicTag(const_cast<char *>("MyLogger"), &tag);

Note: You can use this only when you are sure the function is really never modifying the string passed (i.e. when the function could be declared as const char *, but it is not, perhaps because the library writer has forgotten to add it). An attempt to modify a string literal is an undefined behaviour and on many platforms it results in a crash. If you are not sure, you need to make a writeable copy of the string, which may be dynamically allocated or even stack allocated, when you know some upper limit for the string size.

Community
  • 1
  • 1
Suma
  • 33,181
  • 16
  • 123
  • 191
  • i am using VxWorks 6.8 compiler – venkysmarty Sep 19 '11 at 08:41
  • @NickSoft You cannot add const - that is the problem we are solving in this question, as the library function argument is char *, not const char *. – Suma May 06 '13 at 06:26
  • @Suma then it's generally a bad idea to use a const string literal in a non-constant context. In this case the first argument of the method DynamicTag is non const, so a const shouldn't be passed. So the correct solution should be to make a copy (with strdup for example) and pass the copy. like `char *str; strdup(str, "MyLogger"); g_pCallback->DynamicTag(str, &tag); free(str);`. However if it's know that it's a bad declaration (if the function does not change an argument it should be const) then the `const_cast` is ok. – NickSoft May 10 '13 at 15:49
  • 1
    @NickSoft The string literal IS copied to a local variable, which is modifiable. – Suma May 10 '13 at 18:43
  • The string is not copied at all, only the pointer is assigned to strMyLogger. if DynamicTag() changes the string, the program will crash because string constants should not be changed.. So it should be strdup()'d before usage as a non-const argument – NickSoft Jun 14 '13 at 12:42
  • 1
    @NickSoft This is not how it works. char strMyLogger[]="MyLogger" creates a copy of the string. If you would like to copy the pointer only, you have to write char *strMyLogger="MyLogger" instead. – Suma Jun 14 '13 at 12:45
  • 1
    @Suma Well. That was something I didn't know. Sorry for being stubborn. I tested that and you are right. I always thought that it's creates a pointer to a constant, but I guess it's like any other array initializer. It seams that even this way: const char xxx = "yyy"; it still makes a copy (at least gcc). – NickSoft Jun 17 '13 at 09:13
2

Given you can't change DynamicTag, you have to change the way you call it. You can use, for instance:

char descr[] = "MyLogger";
g_pCallback->DynamicTag(descr, &tag);

Given pDesc is declared as an [in] argument means it would probably not be changed, so you might get away with casting the const away, but that's a bad habit.

Eran
  • 21,632
  • 6
  • 56
  • 89
1

Pass that value as an array.

int tag =0;
char arr[] = "MyLogger";
g_pCallback->DynamicTag(arr, &tag);
iammilind
  • 68,093
  • 33
  • 169
  • 336