gpt4 book ai didi

c - 为什么 GLib 在这些函数中不使用 'const'?

转载 作者:太空狗 更新时间:2023-10-29 15:00:32 24 4
gpt4 key购买 nike

我有一个关于 GLib 的简单问题。

我有以下代码:

static const char *words[] = { "one", "two", "three", NULL };

void main() {
puts(g_strjoinv("+", words));
}

此代码打印one+two+three。它使用连接字符串的 GLib 函数。

signature该功能是:

char *g_strjoinv (const char *separator, char **str_array);

(确切地说,GLib 使用的是gchar,而不是char,但我们忽略这一点。)

现在,我想知道为什么参数是 char **str_array 而不是 const char **str_array。它迫使我进行显式转换以消除编译器的警告(“预期的 'char **' 但参数类型为 'const char **'”):

  puts(g_strjoinv("+", (char **)words));

我看GLib's reference我看到那里的所有函数都是这样定义的:它们接受char **,而不是const char **

这是为什么呢?为什么 GLib 不使用 const char **

需要使用显式转换来摆脱 const 使我的代码不那么安全(因为编译器不再检查参数的兼容性)。这也让我感到紧张,因为 GLib 没有“签署契约(Contract)”说它不会更改我的数据。

最佳答案

您问题中的假设是,如果 g_strjoinv() 的第二个参数被声明为 const char ** 类型,那么您可以轻松地传递一个const char ** 或一个 char ** 到它。

不幸的是,这不是真的。如 this question from the comp.lang.c FAQ 中所述,使用指向 T 的指针(对于任何类型 T),其中指向 const T 的指针是可以预期的,但只有在不匹配的地方在间接的顶层。也就是说,您可以在需要 const char * 的地方传递一个 char *,但您不能(没有强制转换)传递一个 char ** 应该是 const char **,因为在这种情况下,不匹配发生在间接的第二层。链接的问题详细解释了为什么它以这种方式工作,这“有点晦涩”。

所以结果是没有类型(在 C 中)可以同时接受 char **const char ** 至少其中之一需要类型转换。在这种情况下,除了方便之外,可能没有太多理由更喜欢其中任何一个,图书馆作者显然决定选择前者。作为纯粹的猜测,我猜想传递一个 char ** 比传递一个 const char ** 稍微更常见一些,所以他们选择的选项可能更方便。

在您的情况下,您可以从数组的定义中删除 const 限定符。如果您喜欢 const,这可能看起来是一种糟糕的形式,但是由于您有一个指向字符串文字的指针数组,如果有任何尝试写入它们,您的程序极有可能大声提示并失败无论如何,所以在这种特殊情况下你并没有真正以任何有意义的方式失去安全。尽管尝试修改它们是未定义的行为,但字符串文字在 C 中具有 char 数组类型,而不是 const char 数组(与 C++ 不同)。

稍微有点晦涩,但即使你可以将它作为 const char ** 传递,这里的函数仍然可以修改指针,即使它不能修改它们指向的内容,只是以不同的方式造成困惑,因此函数做出的 promise 仍然不能保证您传递给函数的内容不会以某种方式改变。

关于c - 为什么 GLib 在这些函数中不使用 'const'?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24190697/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com