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

3

8

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?

Theatricals answered 2/10, 2013 at 7:31 Comment(1)
Wow, I didn't know you could get such warnings on explicit casts... Good to know in C++, this can force the explicit use of const_cast instead of C-style casts...Platyhelminth
B
16

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.

Blackleg answered 2/10, 2013 at 7:35 Comment(2)
A view in the code of the external lib reveals that the devs just didn't care to mark the parameter as const. Nonetheless, using the copying approach. Will not impact performance, it just didn't feel right. But if this is the adviced way to do, I am going for it.Theatricals
Ask the devs to change the library headerDigitalis
A
8

You could use a union.

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

chrptrs.cchr; // const char *
chrptrs.chr;  // char *
Artillery answered 2/10, 2013 at 7:36 Comment(0)
I
0

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.

Idaidae answered 2/10, 2013 at 9:12 Comment(4)
Using your approach will result in the warning warning: cast discards ‘__attribute__((const))’ qualifier from pointer target type [-Wcast-qual]. This is, however, not enabled by default in gcc but enabled due to the projects policy with -Wcast-qualTheatricals
Well, I was not expecting that you wanted to remove a warning that you asked the compiler to produce... Then your only approach is Gung Foo's.Idaidae
This way it sounds like I am doing nonsense. But as phrased in my question, "you" is not me alone, but a larger group of devs, and I am only a minor contributor - so I can't decide to remove warnings from the build system as these are policy decisions.Theatricals
Please don't take me wrong. I was not meaning that you were doing nonsense, just that it was a bit surprising. :-)Idaidae

© 2022 - 2024 — McMap. All rights reserved.