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?
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.
You could use a union.
union charunion {
char *chr;
const char* cchr;
} chrptrs;
chrptrs.cchr; // const char *
chrptrs.chr; // char *
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With