What is the correct way of casting const char* to char* without changing the API and not getting a warning

StackOverflow https://stackoverflow.com/questions/19131965

Question

In my plain C99 project, I have an external C library that defines an interface (via GObject interfaces) that I need to implement:

void interface_function (const char *address, [...]);

Now, within the implementation (that I need to write) I need to call some other functions from a different library (so I can't change them) to which I need to pass *address, but their method signature omit the const keyword:

void some_api_function (char *address, [...]);

Now, if I simply pass *address down to some_api_function, I will get the compiler warning:

warning: passing argument 1 of ‘some_api_function’ discards ‘const’ qualifier from pointer target type [enabled by default]

I tried explicitly casting to char * in the function call like this:

`some_api_function ((char*) address, [...]) { ... }

but then I just get another warning:

warning: cast discards ‘__attribute__((const))’ qualifier from pointer target type [-Wcast-qual]

The problem is, that this is a larger C project with many people working on and policy is that -Werror is enabled and no code emitting warnings on compile is accepted into the mainline source code.

I can't change the interface definition because it is from a third party, and I can't change the API definitions of the external libraries, either. I know that *address is not modified in the external library (it could be const, but as I said I can't change that)

I also know that to solve this issue, I could just create a copy of the const char* into char *, but that doesn't feel right to me because it involves a unnecessary copy operation .

So what is the elegant or 'right' way to do this?

Était-ce utile?

La solution

For absolute safety I'd deep copy the string and profile the performance impact. The author of the function makes no guarantee that they will not modify the string. If a parameter is marked const char* there is an implication that the string will not be changed by the function.

There are other choices; casting via (void*) or a clever union trick (see Gung Foo's answer), but neither will guarantee program stability.

Autres conseils

You could use a union.

union charunion {
   char *chr;
   const char* cchr;
} chrptrs;

chrptrs.cchr; // const char *
chrptrs.chr;  // char *

Warnings are there for a reason. As Bathseheeba says, the declaration makes no guarantee that the function will not modify the value, so if you know what you are doing -i.e. you know the function will not try to modify the value pointed by 'address'-, you can remove the warning by doing this:

void interface_function (const char *address, [...])
{
    char *chrptr=(char *)address;
    [...]
    some_api_function (chrptr, [...]);
    [...]
 }

EDIT: I was answering before you commented that you were going with Bathsheeba's suggestion. Good choice.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top