Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在不更改API和不获得警告的情况下,将const char*强制转换为char*的正确方法是什么_C_Gcc_Constants_Glib_Gobject - Fatal编程技术网

在不更改API和不获得警告的情况下,将const char*强制转换为char*的正确方法是什么

在不更改API和不获得警告的情况下,将const char*强制转换为char*的正确方法是什么,c,gcc,constants,glib,gobject,C,Gcc,Constants,Glib,Gobject,在我的纯C99项目中,我有一个外部C库,它定义了我需要实现的接口(via): void interface_function (const char *address, [...]); 现在,在实现(我需要编写)中,我需要从不同的库(因此我无法更改它们)调用一些其他函数,我需要将*地址,但它们的方法签名忽略了常量关键字: void some_api_function (char *address, [...]); 现在,如果我只是将*地址传递到某个api函数,我将得到编译器警告: warni

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

void interface_function (const char *address, [...]);
现在,在实现(我需要编写)中,我需要从不同的库(因此我无法更改它们)调用一些其他函数,我需要将
*地址
,但它们的方法签名忽略了
常量
关键字:

void some_api_function (char *address, [...]);
现在,如果我只是将
*地址
传递到
某个api函数
,我将得到编译器警告:

warning: passing argument 1 of ‘some_api_function’ discards ‘const’ qualifier from pointer target type [enabled by default]
warning: cast discards ‘__attribute__((const))’ qualifier from pointer target type [-Wcast-qual]
我尝试在函数调用中显式强制转换为
char*
,如下所示:

`some_api_function ((char*) address, [...]) { ... }
但我又得到了另一个警告:

warning: passing argument 1 of ‘some_api_function’ discards ‘const’ qualifier from pointer target type [enabled by default]
warning: cast discards ‘__attribute__((const))’ qualifier from pointer target type [-Wcast-qual]
问题是,这是一个更大的C项目,有许多人参与其中,策略是启用
-Werror
,并且主线源代码不接受在编译时发出警告的代码

我不能更改接口定义,因为它来自第三方,而且我也不能更改外部库的API定义。我知道,
*地址
不会在外部库中修改(它可能是常量,但正如我所说的,我无法更改)

我还知道,要解决这个问题,我可以将
const char*
的副本创建到
char*
,但我觉得这不对,因为它涉及不必要的复制操作


那么,什么是优雅或“正确”的方法呢?

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

还有其他选择;通过(void*)或巧妙的联合技巧(见工夫的答案)施放,但两者都不能保证节目的稳定性。

你可以使用联合

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

chrptrs.cchr; // const char *
chrptrs.chr;  // char *

警告的存在是有原因的。正如Bathseheeba所说,该声明并不保证函数不会修改该值,因此,如果您知道自己正在做什么,即您知道函数不会尝试修改“address”所指的值,则可以通过执行以下操作来删除警告:

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


编辑:在你评论你同意芭丝谢芭的建议之前,我正在回答。不错的选择

哇,我不知道你可以在显式播放中得到这样的警告。。。很好的了解C++,这可以强制使用const转换而不是C样式的转换。外部LIB代码中的一个视图显示DVS不关心将参数标记为const。尽管如此,使用复制方法。不会影响性能,只是感觉不对。但是,如果这是建议的方法,我会去做。请开发人员更改库标题。使用您的方法将导致警告
警告:从指针目标类型[-Wcast qual]
中丢弃“\u属性(const))”限定符。但是,在gcc中默认情况下,这不是启用的,而是由于使用
-Wcast-qual
的项目策略启用的。好吧,我没想到您希望删除您要求编译器生成的警告。。。那么你唯一的方法就是工夫。这样听起来我好像在胡说八道。但正如我在问题中所说,“你”不是我一个人,而是一个更大的开发人员群体,我只是一个次要的贡献者——所以我不能决定从构建系统中删除警告,因为这些都是策略决定。请不要误解我。我不是说你在胡说八道,只是说这有点令人惊讶。:-)