Re: [[gnomemm] Gnome::UI::Items::IconXpm: wrong data type for xpm's?]
- From: Ole Laursen <olau hardworking dk>
- To: gnomemm-list gnome org
- Subject: Re: [[gnomemm] Gnome::UI::Items::IconXpm: wrong data type for xpm's?]
- Date: 18 Feb 2003 19:41:05 +0100
Murray Cumming <murrayc usa net> writes:
> ERDI Gergo <cactus cactus rulez org> wrote:
> > I would expect Gnome::UI::Items::IconXpm to work with exactly the kind of
> > type that including an 'xpm' file produces, however, that's not the case:
> >
> > form-win.cc: In member function `void
> > Guikachu::GUI::FormWindow::widget_menu_cb(unsigned int, unsigned int,
> > Guikachu::Widget*)':
> > form-win.cc:480: invalid conversion from `char**' to `const gchar**'
> > form-win.cc:480: initializing argument 1 of `
> > Gnome::UI::Items::IconXpm::IconXpm(const gchar**)'
>
> Maybe const gchar** is not const (gchar**).
Yes, the only const part is the characters:
(const gchar) **
If you use
gchar const * const *
it would be fine since everything is then const. I've just checked it
with GCC.
I remember having read about the reason for the problem. I've found a
quote on comp.lang.c++ from a C FAQ book:
11.10: Why can't I pass a char ** to a function which expects a
const char **?
A: You can use a pointer-to-T (for any type T) where a pointer-to-
const-T is expected. However, the rule (an explicit exception)
which permits slight mismatches in qualified pointer types is
not applied recursively, but only at the top level.
(const char ** is pointer-to-pointer-to-const-char, and the
exception therefore does not apply.)
The reason that you cannot assign a char ** value to a
const char ** pointer is somewhat obscure. Given that the const
qualifier exists at all, the compiler would like to help you
keep your promises not to modify const values. That's why you
can assign a char * to a const char *, but not the other way
around: it's clearly safe to "add" const-ness to a simple
pointer, but it would be dangerous to take it away. However,
suppose you performed the following more complicated series of
assignments:
const char c = 'x'; /* 1 */
char *p1; /* 2 */
const char **p2 = &p1; /* 3 */
*p2 = &c; /* 4 */
*p1 = 'X'; /* 5 */
In line 3, we assign a char ** to a const char **. (The
compiler should complain.) In line 4, we assign a const char *
to a const char *; this is clearly legal. In line 5, we modify
what a char * points to -- this is supposed to be legal.
However, p1 ends up pointing to c, which is const. This came
about in line 4, because *p2 was really p1. This was set up in
line 3, which is an assignment of a form that is disallowed, and
this is exactly *why* line 3 is disallowed.
Assigning a char ** to a const char ** (as in line 3, and in the
original question) is not immediately dangerous. But it sets up
a situation in which p2's promise -- that the ultimately-pointed-
to value won't be modified -- cannot be kept.
(C++ has more complicated rules for assigning const-qualified
pointers which let you make more kinds of assignments without
incurring warnings, but still protect against inadvertent
attempts to modify const values. C++ would still not allow
assigning a char ** to a const char **, but it would let you get
away with assigning a char ** to a const char * const *.)
In C, you must use explicit casts (e.g. (const char **) in this
case) when assigning (or passing) pointers which have qualifier
mismatches at other than the first level of indirection.
--
Ole Laursen
http://www.cs.auc.dk/~olau/
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]