What is the correct way to cast const char * to char * without changing the API and not receiving a warning

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

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

Now, as part of the implementation (which I need to write), I need to call some other functions from another library (therefore, I cannot change them), to which I need to pass *address , but their method signature skip the const keyword:

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

Now, if I just pass *address to some_api_function , I will get a 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 a function call as follows:

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

but then I 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, in which many people work, and the policy is that -Werror included, and no warnings about code compilation are received in the mainline source code.

I canโ€™t change the definition of the interface, because itโ€™s from a third party, and I also canโ€™t change the API definitions of external libraries. I know that *address does not change in the external library (it can be const, but, as I said, I can not change this)

I also know that to solve this problem, I could just create a copy of const char* in char * , but this does not seem right to me because it is due to an unnecessary copy operation.

So what is an elegant or โ€œrightโ€ way to do this?

+6
source share
3 answers

For absolute security, I would deeply copy the line and analyze the impact of performance. The author of the function does not guarantee that they will not modify the string. If the parameter is marked with const char* , it is assumed that the string will not be changed by the function.

There are other options; (void *) or clever allied trick (see Gung Foo answer), but none of them guarantee the stability of the program.

+13
source

You can use union.

 union charunion { char *chr; const char* cchr; } chrptrs; chrptrs.cchr; // const char * chrptrs.chr; // char * 
+6
source

Warnings exist for some reason. According to Bathseheeba, the declaration does not guarantee that the function will not change the value, so if you know what you are doing - i.e. you know that the function will not try to change the value indicated by the "address", you can remove the warning by doing the following:

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

EDIT: I replied before you commented that you were coming with a Bathsheeba suggestion. A good choice.

0
source

Source: https://habr.com/ru/post/955080/


All Articles