wozniak@utkux1.utk.edu (Bryon Lape) (06/11/90)
Recently I tried to write a generic swap routine using void pointers, but it did not work. Below is an example: #include<stdio.h> void generic_swap(void *, void *); main() { short int x=4, y=50; printf("\n%d %d", x ,y); generic_swap(&x, &y); printf("\n%d %d", x, y); } generic_swap(void *, void *) { void *temp; temp = b; b = a; a = temp; } I ran this in Quick C 2.0 and the values DID exchange within the function, but not on the outside. Anyone know what might be wrong? -bryon lape-
whipple@sun.udel.edu (Peter Adams Whipple) (06/11/90)
In article <1990Jun11.133729.6575@cs.utk.edu> wozniak@utkux1.utk.edu (Bryon Lape) writes: > > Recently I tried to write a generic swap routine using void >pointers, but it did not work. Below is an example: [stuff deleted] >generic_swap(void *, void *) >{ > void *temp; > > temp = b; > b = a; > a = temp; >} You are swapping the pointer (which are local values) instead of swapping the values (*a and *b). If you can use *a, *b, and *temp, the routine will work as expected. Off-hand, I don't remember if you can dereference a void *. -- Peter
karl@haddock.ima.isc.com (Karl Heuer) (06/11/90)
In article <1990Jun11.133729.6575@cs.utk.edu> wozniak@utkux1.utk.edu (Bryon Lape) writes: >generic_swap(void *, void *) { > void *temp; temp = b; b = a; a = temp; >} [0] This won't even compile, since you left out the names of the arguments. Please, people, try to post code fragments directly from the test source if possible, rather than keying them in. [1] You have the wrong level of indirection. The objects to be swapped were passed by reference, so you need to dereference them (`*a', `*b') in order to swap the actual objects. But you can't, because this routine doesn't know the types of the pointed-to objects. You could use void generic_swap(void *pa, void *pb, size_t n) { void *ptmp = malloc(n); assert(ptmp != NULL); memcpy(ptmp, pb, n); memcpy(pb, pa, n); memcpy(pa, ptmp, n); } but this is pretty silly. Just code the bloody thing inline, rather than trying to use a generic routine. [2] Note to readers: please don't followup this thread unless you've already read the relevant part of the Frequently Asked Questions document, and have something *new* to say. I don't want to see the XOR hack being discussed to death again. Karl W. Z. Heuer (karl@ima.ima.isc.com or harvard!ima!karl), The Walking Lint
dankg@sandstorm.Berkeley.EDU (Dan KoGai) (06/12/90)
>swap the actual objects. But you can't, because this routine doesn't know the>...You could use > void generic_swap(void *pa, void *pb, size_t n) { > void *ptmp = malloc(n); assert(ptmp != NULL); > memcpy(ptmp, pb, n); memcpy(pb, pa, n); memcpy(pa, ptmp, n); > } >but this is pretty silly. Just code the bloody thing inline, rather than >trying to use a generic routine. I agree: Usually we don't swap objects so large that requires memcpy(). Instead we swap pointers to the objects. But C sometimes allows assignment of objects larger than size of register, such as structs and some compilers allow to pass structs as arguments (not ptr to structs). Here's my quick & dirty macro void *temp; #define swap(type, x, y) temp = (type *)malloc(sizeof(type));\ *(type)temp = x; x = y ; y = *(type)temp; free(temp) Since this is a macro, it should work even though your compiler does not allow passing structs as arguments (struct assignment is valid since K&R while struct as argument is not). But since it's a macro, handle with care (even better for C++ #inline) >[2] Note to readers: please don't followup this thread unless you've already >read the relevant part of the Frequently Asked Questions document, and have >something *new* to say. I don't want to see the XOR hack being discussed to >death again. Since I haven't seen my macro version, I decided to follow. Dan Kogai (dankg@ocf.bekeley.edu)
zhu@cs.jhu.edu (Benjamin Zhu) (06/13/90)
In article <1990Jun11.214844.21531@agate.berkeley.edu> dankg@sandstorm.Berkeley.EDU (Dan KoGai) writes: >>swap the actual objects. But you can't, because this routine doesn't know the>...You could use >> void generic_swap(void *pa, void *pb, size_t n) { >> void *ptmp = malloc(n); assert(ptmp != NULL); >> memcpy(ptmp, pb, n); memcpy(pb, pa, n); memcpy(pa, ptmp, n); >> } >>but this is pretty silly. Just code the bloody thing inline, rather than >>trying to use a generic routine. > > I agree: Usually we don't swap objects so large that requires >memcpy(). Instead we swap pointers to the objects. But C sometimes >allows assignment of objects larger than size of register, such as >structs and some compilers allow to pass structs as arguments (not ptr >to structs). Here's my quick & dirty macro > >void *temp; >#define swap(type, x, y) temp = (type *)malloc(sizeof(type));\ > *(type)temp = x; x = y ; y = *(type)temp; free(temp) ^^^^ ^^^^ I suppose you want to write (type *) instead. Otherwise, it looks OK. > > Since this is a macro, it should work even though your compiler >does not allow passing structs as arguments (struct assignment is valid >since K&R while struct as argument is not). But since it's a macro, >handle with care (even better for C++ #inline) > >>[2] Note to readers: please don't followup this thread unless you've already >>read the relevant part of the Frequently Asked Questions document, and have >>something *new* to say. I don't want to see the XOR hack being discussed to >>death again. > > Since I haven't seen my macro version, I decided to follow. > >Dan Kogai (dankg@ocf.bekeley.edu) Benjamin Zhu +=========================================================================+ +Disclaimer: + + I do not represent Johns Hopkins, Johns Hopkins does not + + represent me either. + +==========================================================================
karl@haddock.ima.isc.com (Karl Heuer) (06/13/90)
In article <1990Jun11.214844.21531@agate.berkeley.edu> dankg@sandstorm.Berkeley.EDU (Dan KoGai) writes: >void *temp; >#define swap(type, x, y) temp = (type *)malloc(sizeof(type));\ > *(type)temp = x; x = y ; y = *(type)temp; free(temp) Those casts don't make sense. I think you want #define swap(type, x, y) temp = malloc(sizeof(type));\ *(type *)temp = x; x = y ; y = *(type *)temp; free(temp) > Since this is a macro, it should work even though your compiler >does not allow passing structs as arguments (struct assignment is valid >since K&R while struct as argument is not). Wrong. The three forms of struct copy (assignment, pass by value, return by value) were all added at the same time, shortly after K&R 1 was published. Karl W. Z. Heuer (karl@ima.ima.isc.com or harvard!ima!karl), The Walking Lint