integer -> pointer question
Hi,
When porting packages to IA64, it is very common to come across code where integers are being assigned to pointers. This results in warning messages from the compiler about assigning integers to pointers of a different size.
This is very helpful in the case where a function prototype has been omitted, or the programmer has simply made bad assumptions about the sizes of pointers and integers.
On the other hand, it is not unusual to see void pointers used for storing integers, and the programmer has no intention of ever de-referencing the pointer. Glib and GTK+ make extensive use of this technique.
The problem is that this generates the same warning messages as the first case, and it makes it more difficult to know if a particular package has portability problems.
My question is: Is there a way to assign integers to void pointers without triggering warnings from the compiler?
Thanks
Mike Madore
Software Engineer
TurboLinux, Inc.
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
"Michael" = Michael Madore <[email protected]> writes:
Michael> On the other hand, it is not unusual to see void pointers Michael> used for storing integers, and the programmer has no Michael> intention of ever de-referencing the pointer. Glib and GTK+ Michael> make extensive use of this technique.
Michael> The problem is that this generates the same warning messages Michael> as the first case, and it makes it more difficult to know if Michael> a particular package has portability problems.
Michael> My question is: Is there a way to assign integers to void Michael> pointers without triggering warnings from the compiler?
Hi Michael
Storing integers in void pointers without a cast is simply broken and nobody should do that or to be more precise you cannot expect void * to be the same size as int.
Basically the correct solution is to LART the programmer of the bad code.
Jes
Quoted 2 lines · Michael Madore
My question is: Is there a way to assign integers to void pointers without triggering warnings from the compiler?
I can't see any *good* reason for storing integers into void pointers, if those integers aren't valid memory addresses.
The C language definition requires a diagnostic in this case, regardless of any size issues and gcc emits this diagnostic even on x86, where the two types have the same size:
ues12:~/tmp 68> cat test.c
int main()
{
void *p = 123;
return 0;
}
ues12:~/tmp 69> gcc test.c
test.c: In function `main':
test.c:3: warning: initialization makes pointer from integer without a cast
ues12:~/tmp 70> uname -a
Linux ues12 2.2.12-20 #1 Mon Sep 27 10:40:35 EDT 1999 i686 unknownIf you want to shut up such warnings, do what gcc suggests: cast the integer to void *.
Dan
Quoted 10 lines
Hi Michael
Storing integers in void pointers without a cast is simply broken and nobody should do that or to be more precise you cannot expect void * to be the same size as int.
Basically the correct solution is to LART the programmer of the bad code.
Jes
The code does perform the cast, but since the upper four bytes of the pointer will be meaningless, it's spits out a warning.
Mike
Hi Dan,
Quoted 19 lines
I can't see any *good* reason for storing integers into void pointers, if those integers aren't valid memory addresses.
The C language definition requires a diagnostic in this case, regardless of any size issues and gcc emits this diagnostic even on x86, where the two types have the same size:
ues12:~/tmp 68> cat test.c int main() { void *p = 123; return 0; } ues12:~/tmp 69> gcc test.c test.c: In function `main': test.c:3: warning: initialization makes pointer from integer without a cast ues12:~/tmp 70> uname -a Linux ues12 2.2.12-20 #1 Mon Sep 27 10:40:35 EDT 1999 i686 unknown
Quoted 2 lines
If you want to shut up such warnings, do what gcc suggests: cast the integer to void *.
Sorry, my original post was a little unclear. The compiler spits out a warning even if the programmer uses a cast.
Mike
Quoted 5 lines · Michael Madore
Quoted 2 lines
If you want to shut up such warnings, do what gcc suggests: cast the integer to void *.
Sorry, my original post was a little unclear. The compiler spits out a warning even if the programmer uses a cast.
I can't reproduce this behaviour here:
pcpole65:~ 0 15> gcc -v
Reading specs from /usr/local/lib/gcc-lib/ia64-unknown-linux/2.9-ia64-000216-final/specs
gcc version 2.9-ia64-000216-final
pcpole65:~ 0 16> cat test.c
int main()
{
void *p = (void *)123;
return 0;
}
pcpole65:~ 0 17> gcc test.c
pcpole65:~ 0 18> But if it happens with your toolchain, the logical fix would be to cast the integer to long before casting it to void *. Or, if it's a plain integer constant, just use the 'L' suffix. This shouldn't cause any problems on 32-bit platforms, where int's and long's have the same size.
Dan
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line · Michael Madore
Michael> Hi, When porting packages to IA64, it is very common to Michael> come across code where integers are being assigned to Michael> pointers. This results in warning messages from the Michael> compiler about assigning integers to pointers of a Michael> different size.
Michael> This is very helpful in the case where a function prototype Michael> has been omitted, or the programmer has simply made bad Michael> assumptions about the sizes of pointers and integers.
Michael> On the other hand, it is not unusual to see void pointers Michael> used for storing integers, and the programmer has no Michael> intention of ever de-referencing the pointer. Glib and Michael> GTK+ make extensive use of this technique.
It's sad that GTK/Glib is propagating this poor programming habit. The clean solution is to use a union type such as:
typedef union {
void *v;
long l;
int i;
char c;
float f;
double d;
...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 additional any_type_t variables 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;})
etc.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.
--david
Quoted 4 lines
Quoted 4 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line
"Michael" = Michael Madore <[email protected]> writes:
Hi Michael
Quoted 8 lines
Quoted 8 lines
Storing integers in void pointers without a cast is simply broken and nobody should do that or to be more precise you cannot expect void * to be the same size as int.
Basically the correct solution is to LART the programmer of the bad code.
Jes
Michael> The code does perform the cast, but since the upper four Michael> bytes of the pointer will be meaningless, it's spits out a Michael> warning.
Good point, what they really should be doing is to use long instead of void * then - you know that long = sizeof(void *) but you shouldn't get the error for that.
Jes