Subject: Re: iconv(3) prototype
To: None <mouse@Rodents.Montreal.QC.CA>
From: T.SHIOZAKI <tshiozak@netbsd.org>
List: tech-userlevel
Date: 07/28/2004 17:38:12
From: der Mouse <mouse@Rodents.Montreal.QC.CA>
Subject: Re: iconv(3) prototype
Date: Wed, 28 Jul 2004 03:30:24 -0400 (EDT)
Message-ID: <200407280732.DAA27066@Sparkle.Rodents.Montreal.QC.CA>
> > The point of this problem is that the 2nd argument of iconv() is "a
> > pointer of a pointer". "char *" can be converted to "const char *"
> > explicitly, but "char **" cannot be converted to "const char **"
> > without warning.
>
> Well, without a cast, yes. I've never understood why char ** is
> incompatible with const char **....
Briefly, section 6.5.16.1 of ISO C99 means:
(1) "T" can implicitly be converted to "const T" and
(2) "T *" can implicitly be converted to "const T *",
(3) but "T1 *" cannot implicitly be converted to "T2 *".
Here, T, T1 and T2 are types,
and T1 and T2 are different types from each other.
"const char *" is a different type from "char *", thus
converting from "char **" to "const char **" is corresponding to (3).
The point is a sort of the combination problem between different systems.
For example,
System A declares foo() as: void foo(char **);
System B declares foo() as: void foo(const char **);
If we call it as:
foo((char **)&str);
OK on System A, but NG on System B.
If we call it as:
foo((const char **)&str);
OK on System B, but NG on System A.
They are inconsistent.
If we wish to call it without warnings, we need to write as:
#if SYSTEM_A
foo((char **)&str);
#elif SYSTEM_B
foo((const char **)&str);
#endif
or
(void (*)(char **))foo((char **)&str);
or
(void (*)(const char **))foo((const char **)&str);
--
Takuya SHIOZAKI