2017-08-29 80 views
5

document of iconv,功能简介是这样的:为什么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函数需要一个非const的缓冲区?

我的g ++版本是6.3.0。

+3

请将代码格式设置为文本,而不是图片。 – nwp

+0

功能在哪里不同?你到底什么意思? – user463035818

+3

'const char * * inbuf,'''char ** __ restirct __inbuf,',我猜。 –

回答

5

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); 

他们const**inbuf不同, 所以,如果你想保持两个标准之间移植,你必须不幸的是,要传递一个非const的参数 **inbuf

编辑:由于这是一个双指针,问题更加严重,see my answer here。概括地说,这些规范都没有在任何一个方向兼容...


你作为“的iconv的文档”链接什么是GNU libiconv,其目的是要在平台上使用,唐”的文件t原生提供iconv() - 这个明显遵循SUSv2规范。

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

+0

POSIX 2008与SUSv4相同。他们早已不再分开存在。所以SUSv2和SUSv4不兼容? ;-) –

+0

嗯,不,只要我找到的文件是正确的... –

+0

我会说Posix 1.2008是SUSv2的更新;只是说他们是“不同的标准”(虽然在技术上是正确的)有些误导。在任何情况下,SUSv2列出了'iconv'的两个不同的原型,其中一个在你引用的接口规范中(用'const'),另一个(没有'const')在http: //pubs.opengroup.org/onlinepubs/7908799/xsh/iconv.h.html。这个差异在问题6中得到了解决,但是这留下了两个原型中哪一个适用于SUSv2的问题...... – rici

1

const char * * inbuf,与char ** __ restirct __inbuf ,,我猜。 - Sourav Ghosh

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

使用限制可能实际上在较高的优化级别导致最差的代码。

https://godbolt.org/g/uhfVCe

+2

“*你不能使用'const'和'restrict' *”< - reference?我可以很好地结合在一起(在数据中使用const,在指针上使用restrict),这在语义上是合理的。 –

+0

我确实不确切 - 会删除 –