forwarded message from David Mosberger
Tom Tromey forwarded me the following -
Quoted 1 line · David Mosberger
It's sad that GTK/Glib is propagating this poor programming habit.
The assumption we we make is not that the size of ints and pointers are the same, but simply that it is possible to store small (< 32 bit) integers in a pointer variable.
While this assumption is not ANSI compliant, and I wouldn't defend it on theoretical grounds, in practice it is very portable across the platforms we care about, convenient, and efficient.
The two grounds on which it might be attacked as a poor programming habit would be lack of portability or lack of readability. It's stood up well in porting GTK+ to a large number of platforms, and readability, especially with the cast macros discussed below, is not worse than the alternatives.
It is a bit kludgy, and I'd never use such a thing without looking for a better way of structuring the code. I think the same could be said about most other experienced GTK+ programmers. But it is a nice tool to have around at times.
Quoted 8 lines
The clean solution is to use a union type such as:
typedef union { void *v; long l; int i; char c; float f;
p> double d;
Quoted 11 lines
...other types you might like...; } any_type_t;and then you can assign to a variable of type "
any_type_t" without any ugly casts. It also makes it much clearer what the intended use of the argument in question is. If you don't like the additionalany_type_tvariables you need to declare in return, you can avoid even that by introducing cpp macros of the form:#define int_to_any_type(i) ({any_type_t a; a.i = i;}) #define long_to_any_type(i) ({any_type_t a; a.l = l;})
These are GCC specific. To be portable, you'd have to define (possibly inline) functions instead of macros.
etc.
Quoted 4 lines
Unfortunately, it's unlikely that GTK/Glib will be fixed soon in this respect, so in the meantime, just use the cast "(void *)(long) i" if "i" is an integer.
Simply using a cast like this is a bad idea, since it will break on platforms where sizeof(long) != sizeof(ptr), such as IRIX with some compilation options.
Instead, if you are doing programming using GLib, you should convert using:
GINT_TO_POINTER (i), GUINT_TO_POINTER (i)
GPOINTER_TO_INT (p), GPOINTER_TO_UINT (p)
Which are autoconf'ed to be correct for the platform in use.
Regards,
Owen
Quoted 3 lines
Quoted 3 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line · Owen Taylor
#define
int_to_any_type(i)({any_type_ta; a.i = i;})
Owen> These are GCC specific. To be portable, you'd have to define Owen> (possibly inline) functions instead of macros.
That's true. Since "inline" isn't really ANSI C either, regular functions would have to be used (slow, but so what; I never understood why GNU C is the only C variant to provide statement expressions---it's a critically important feature when translating other languages to C, for example).
Owen> Instead, if you are doing programming using GLib, you should Owen> convert using:
Owen> GINT_TO_POINTER (i), GUINT_TO_POINTER (i) GPOINTER_TO_INT
Owen> (p), GPOINTER_TO_UINT (p)
Owen> Which are autoconf'ed to be correct for the platform in use.
Ah, that's fine then. As long as there is a clean way for source code to express the conversion, I don't really care how it's implemented. Sorry for faulting gtk/glib without checking first (it's been too long since I programmed with this toolkit, so I didn't remember how this was handled... ;-).
--david
Since "inline" isn't really ANSI C either
It is now, though it will be awhile before C9X (C99?) is widespread.
I never understood
why GNU C is the only C variant to provide statement expressions---it's a critically important feature when translating other languages to C, for example).
There is a debate currently on the gcc lists about this. It turns out that statement expressions conflict with the C++ language standard, and it isn't clear if this problem can be solved. This is a problem for g++ because glibc uses statement expressions in some header files, and C++ programs that include those header files may not work. It isn't clear what is going to happen yet, but some people are considering eliminating statement expressions. That probably won't happen, but eliminating or restricting statement expressions in C++ probably will happen.
If you want to use C++, then don't use statement expressions.
Jim