【问题标题】:Why does the iconv function need a non-const inbuffer?为什么 iconv 函数需要非常量缓冲?
【发布时间】:2017-08-29 12:19:11
【问题描述】:

document of iconv中的函数概要是这样的:

#include <iconv.h>

size_t iconv (iconv_t cd, const char* * inbuf, 
      size_t * inbytesleft, 
      char* * outbuf, 
      size_t * outbytesleft);

但是,当我在我的系统中检查iconv.h时,函数概要是这样的:

extern size_t iconv (iconv_t __cd, char **__restirct __inbuf,
      size_t *__restrict __inbytesleft,
      char **__restirct __outbuf,
      size_t *__restrict __outbytesleft);

在这两个函数概要中,一个是const char **,而另一个只是char **。

为什么文档中的功能概要和我系统中的不一样?为什么 iconv 函数需要一个非常量的 inbuffer?

我的g++版本是6.3.0。

【问题讨论】:

  • 请将代码发布为带有代码格式的文本,而不是图片。
  • 功能有何不同?你到底是什么意思?
  • const char* * inbuf, vs. char **__restirct __inbuf,,我猜。

标签: c linux iconv


【解决方案1】:

iconv() 的问题在于它不是 C 标准的一部分,而是在两个不同的标准中指定。其中之一是POSIX-1.2008

#include <iconv.h>

size_t iconv(iconv_t cd, char **restrict inbuf,
       size_t *restrict inbytesleft, char **restrict outbuf,
       size_t *restrict outbytesleft);

另一个是SUSv2

#include <iconv.h>

size_t iconv(iconv_t cd, const char **inbuf, size_t *inbytesleft,
    char **outbuf, size_t *outbytesleft);

它们在 **inbuf**inbuf 之间的区别在于 const因此,如果您想在两种标准之间保持可移植性,不幸的是,您必须通过非 const **inbuf

编辑:因为这是一个双指针,所以问题更严重,see my answer here。简而言之,这些规范在任何一个方向上都不兼容...


您链接为“iconv 文档”的是 GNU libiconv 的文档,它旨在用于不原生提供 iconv() 的平台上——这显然遵循 SUSv2 规范。

您在系统上找到的头文件属于您平台的 C 库 glibc,并且 实现遵循 POSIX-1.2008 规范。

【讨论】:

  • POSIX 2008 与 SUSv4 相同。它们早已不再单独存在。那么SUSv2和SUSv4不兼容? ;-)
  • 我会说 Posix 1.2008 是对 SUSv2 的更新;仅仅说它们是“不同的标准”(虽然在技术上是正确的)有点误导。无论如何,SUSv2 为iconv 列出了两个不同的原型,其中一个在您引用的接口规范中(带有const),另一个(不带const)在@987654324 的标头规范中@。差异已在第 6 期中得到解决,但这留下了两个原型中的哪一个适用于 SUSv2 的问题......
  • ...这里,唯一真正的指南是pubs.opengroup.org/onlinepubs/7908799/xsh/interfaces.html 中的声明:“XSI 兼容系统的实现将使所有必要的符号可见如标题部分所述 本规范。” (强调)这似乎暗示iconv.h 规范是要使用的规范,因此glibc 原型中的const 是不正确的。 (这也将与后来的变化保持一致。)
  • @felix:好的,Gnu libiconv,如果你愿意的话。不管 iconv.h 来自哪里,在我看来都是错误的。 :)
  • 我想你会发现 Gnu libiconv 也不再有const。 (变更日志表明它基本上在 2007 年左右被删除。)
【解决方案2】:

const char* * inbuf,与 char **__restirct __inbuf,我猜。 – 苏拉夫 天哪

确实 - 限制通知编译器指针对象不会改变。这个声明实际上是通过这种方式完成的,以便更好地优化生成的代码。

在更高的优化级别上使用restrict实际上可能会导致最糟糕的代码。

https://godbolt.org/g/uhfVCe

【讨论】:

  • "你不能使用constrestrict" const 应用于数据,restrict 应用于指针),这在语义上是有意义的。
  • 我确实不准确 - 将删除
猜你喜欢
  • 2018-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-02
  • 2016-07-13
  • 1970-01-01
  • 1970-01-01
  • 2019-04-21
相关资源
最近更新 更多