Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

iconv(3) protype mismatch with POSIX

3 views
Skip to first unread message

Kamil Rytarowski

unread,
May 28, 2016, 9:47:04 AM5/28/16
to
This was already noted in 2006

http://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=33125


NetBSD iconv(3):

size_t
iconv(iconv_t cd, const char ** restrict src, size_t * restrict srcleft,
char ** restrict dst, size_t * restrict dstleft);


It says that:
Historically, the definition of iconv has not been consistent across
operating systems. This is due to an unfortunate historical mistake,
documented in this e-mail:

https://www5.opengroup.org/sophocles2/show_mail.tpl?&source=L&listname=austin-group-l&id=7404.
The standards page for the header file <iconv.h> defined the second
argument of iconv() as char **, but the standards page for the iconv()
implementation defined it as const char **. The standards committee
later chose to change the function definition to follow the header file
definition (without const), even though the version with const is
arguably more correct. NetBSD has always used the const form. It was
decided to reject the committee's regression and become (technically)
incompatible. GNU libiconv has taken the same route:

http://www.gnu.org/savannah-checkouts/gnu/libiconv/documentation/libiconv-1.14/.
Most third party software affected by this issue already handles it
during configuration.


It's no longer true for gnu libiconv. They gave up and removed "const"
in 2009:

http://git.savannah.gnu.org/cgit/libiconv.git/log/?qt=grep&q=iconv

Perhaps we are the only ones left there and new software (like .NET or
Qt5) no longer handles the "const" variation. Can we legalize the POSIX
mistake from the past and align to the rest of world?

David Holland

unread,
May 28, 2016, 9:16:09 PM5/28/16
to
On Sat, May 28, 2016 at 03:45:35PM +0200, Kamil Rytarowski wrote:
> [iconv const mess]

So it appears that given

size_t
iconv(iconv_t cd,
char **restrict src, size_t *restrict srcleft,
char **restrict dst, size_t *restrict dstleft);
size_t
__iconv_const(iconv_t cd,
const char **restrict src, size_t *restrict srcleft,
char **restrict dst, size_t *restrict dstleft);

one can do

#define iconv(cd, src, srcleft, dst, dstleft) \
_Generic(src, const char **: __iconv_const, default: iconv) \
(cd, src, srcleft, dst, dstleft)

and at least with the gcc5 in current it seems to match as intended.
Plus if anything unexpected comes up #undef iconv makes the magic go
away.

(Also, because implementing things as macros is not 100% benign it
should maybe be disabled by default in strict posix mode.)

Anyone want to check if it works in clang?

--
David A. Holland
dhol...@netbsd.org

Kamil Rytarowski

unread,
May 28, 2016, 10:00:15 PM5/28/16
to
This is an interesting exercise to use C11.. however:
1. Not all ports moved to gcc 4.9+,
2. pcc doesn't support it,
3. it won't work as a valid and acceptable C++ code.
4. Many software expects system headers to be C89, GNU89 etc, and
doesn't request C11.

I'm unsure what will happen with all these tools to detect system
capabilities.

How about the Solaris 11 move? Leave "extern" option for those who rally
want it and SUS/POSIX for others.

0 new messages