Reputation: 6814
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?
Upvotes: 8
Views: 7505
Reputation: 380
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.
Upvotes: 0
Reputation: 13558
You could use a union.
union charunion {
char *chr;
const char* cchr;
} chrptrs;
chrptrs.cchr; // const char *
chrptrs.chr; // char *
Upvotes: 8
Reputation: 234725
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.
Upvotes: 16