Hi,

Since revision 9898 the LongBool type behaves differently. This was done
for Delphi compatibility (see log message here
http://svn.freepascal.org/cgi-bin/viewvc.cgi?view=rev&revision=9898). In
short, if B is LongBool, then "B := true;" sets now B to $ffffffff
(while previously it set B to 1).

This has some unexpected results. GTK's (glib and such) gboolean type is
defined as equal to LongBool, as it was very comfortable when doing GTK
programming. Unfortunately, GTK doesn't officially tolerate gboolean
values other than 0 and 1 (see docs
http://library.gnome.org/devel/glib/unstable/glib-Basic-Types.html#gboolean).
In most of the cases, this is invisible and things work as before, but:

1. Sometimes we get warnings like

(view3dscene:7005): GLib-GObject-WARNING **: value "TRUE" of type
`gboolean' is invalid or out of range for property
`do-overwrite-confirmation' of type `gboolean'

(when calling gtk_file_chooser_set_do_overwrite_confirmation(..., true))

2. The really ugly things happen when some library actually assumes that
the only valid values are 0 and 1. In particular, this bug bite me bad
because GtkGLExt implementation did in one place a comparison of a
gboolean value "direct" like "if (direct == TRUE) ....". The "TRUE" in
this code comes from Glib headers and is just "1", so passing Pascal's
"true" literal ($ffffffff) to this function is treated as false. (With
quite catastrophic results in this particular case, as then GtkGLExt
gives me "indirect" OpenGL context, which is a software context, without
GPU shaders and nearly useless for interesting OpenGL fun.)

IOW, we do have a tricky problem here. The tricky thing is that a lot of
GTK-related code may seem to work, but mysteriously fail in particular
cases. Anyone sees a nice solution?

Some quick ideas:

1. The solution putting most work on compiler developers would be to
implement a new type like "LongBool01", that is assignment-compatible
with other boolean types, and internally always guaranteed to be 0
(false) or 1 (true). IOW, LongBool01 would be something like how
LongBool behaved before revision 9898 (except LongBool never guaranteed
this 0/1 behavior, but it seems we need a type that does guarantee this).

Then define gboolean = LongBool01, and everything magically works
everywhere. Users do not have to change anything. Compiler developers
have to deal with yet another boolean type inside the compiler.

2. The second option would be to put things in user hands, and force us
to correct our code. So gboolean should be defined like

  gboolean = (gfalse = 0, gtrue = 1);

and we need a trivial functions to convert from/to gboolean and normal
boolean, like

function ToGBoolean(const A: boolean): GBoolean; inline;
const
  T: array [boolean] of GBoolean = (gfalse, gtrue);
begin
  Result := T[A];
end;

and similar to convert GBoolean to boolean. The uncomfortable thing
about this is that all GTK/Glib/GtkGLExt/etc. code will have to be
corrected and "infested" with these dummy gboolean<->boolean conversions.

Any ideas?

Michalis
_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply via email to