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

Frage

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?

War es hilfreich?

Lösung

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.

Andere Tipps

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top