在不更改API且未收到警告的情况下,将const char*转换为char*的正确方法是什么?

Dyn*_*lon 8 c gcc const gobject glib

在我的普通C99项目中,我有一个外部C库,它定义了我需要实现的接口(通过GObject接口):

void interface_function (const char *address, [...]);
Run Code Online (Sandbox Code Playgroud)

现在,在实现(我需要编写)中,我需要从我需要传递的不同库中调用其他函数(因此我无法更改它们)*address,但是他们的方法签名省略了const关键字:

void some_api_function (char *address, [...]);
Run Code Online (Sandbox Code Playgroud)

现在,如果我简单地传递*addresssome_api_function我,我将得到编译器警告:

warning: passing argument 1 of ‘some_api_function’ discards ‘const’ qualifier from pointer target type [enabled by default]
Run Code Online (Sandbox Code Playgroud)

我尝试char *在函数调用中明确地转换为:

`some_api_function ((char*) address, [...]) { ... }
Run Code Online (Sandbox Code Playgroud)

但后来我又得到另一个警告:

warning: cast discards ‘__attribute__((const))’ qualifier from pointer target type [-Wcast-qual]
Run Code Online (Sandbox Code Playgroud)

问题是,这是一个更大的C项目,有很多人在工作,并且-Werror启用了策略,并且在主线源代码中没有接受编译时发出警告的代码.

我无法更改接口定义,因为它来自第三方,我也无法更改外部库的API定义.我知道*address在外部库中没有修改它(它可能是const,但正如我所说,我不能改变它)

我也知道要解决这个问题,我可以创建一个const char*into 的副本char *,但这对我来说感觉不对,因为它涉及不必要的复制操作.

那么优雅或"正确"的方式是什么?

Bat*_*eba 15

为了绝对安全,我会深入复制字符串并描述性能影响.函数的作者不保证他们不会修改字符串.如果标记了参数,则表明const char*该函数不会更改该字符串.

还有其他选择; 通过(void*)或巧妙的联合技巧(参见Gung Foo的答案),但两者都不能保证程序的稳定性.


Gun*_*Foo 7

你可以使用一个联盟.

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

chrptrs.cchr; // const char *
chrptrs.chr;  // char *
Run Code Online (Sandbox Code Playgroud)