Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 288
Dynalon Avatar asked Oct 02 '13 07:10

Dynalon


2 Answers

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.

like image 126
Bathsheba Avatar answered Sep 20 '22 16:09

Bathsheba


You could use a union.

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

chrptrs.cchr; // const char *
chrptrs.chr;  // char *
like image 27
Gung Foo Avatar answered Sep 20 '22 16:09

Gung Foo