Re: [[gnomemm] Gnome::UI::Items::IconXpm: wrong data type for xpm's?]



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]