Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/18/84; site brl-tgr.ARPA Path: utzoo!linus!philabs!cmcl2!seismo!brl-tgr!tgr!tribble_acn%uta.csnet@csnet-relay.arpa From: tribble_acn%uta.csnet@csnet-relay.arpa (David Tribble) Newsgroups: net.lang.c Subject: re: c types problem Message-ID: <1334@brl-tgr.ARPA> Date: Wed, 8-Jan-86 05:47:40 EST Article-I.D.: brl-tgr.1334 Posted: Wed Jan 8 05:47:40 1986 Date-Received: Fri, 10-Jan-86 06:45:36 EST Sender: news@brl-tgr.ARPA Lines: 55 In article <870@kuling.UUCP> gostas@kuling.UUCP writes: >The formal (but ugly) way to solve this would probably be to use a union >for all (about 10) types. But now I wonder if anyone has a simpler but >reasonably portable solution? The only way that is truly portable that comes to mind is to use a union. However, the following way works on many (not all) machines and is somewhat portable (meaning it is not truly portable): foo (typ, arg) int typ; double arg; { char* argp; ... argp = (char*) &arg; switch (typ) { case CHR: c = *(char*)argp; case INT: i = *(int*)argp; case FLT: f = *(float*)argp; case DBL: d = *(double*)argp; ... ... } } foo is the routine that is passed the arg or unknown type, and foo knows what type arg is by the value of typ. The idea is to pass the parm (declared as a type that will probably be aligned, thus 'double'), take its address (which is usually on the stack), cast the address (pointer) to the appropriate pointer type, then de-reference the casted pointer. This is based on the assumption that parameters of different types will reside at the same location (ie, their lower bytes have the same alignment). Yes, it's hokey, and yes, it will not work on machines that align function arguments in funny ways. ----- Another variant to this scheme is to call foo passing it the address of the object, declaring foo- foo (typ, argp) int typ; char* argp; This solves the alignment problem. However, since you can only take the address of an lvalue, you cannot pass foo the address of an expression. This scheme suffers from nonportability since casting pointers to different types is wierd on some machines. Given my choice, I would probably use the pointer-passing scheme, since it is (mostly) portable and doesn't require macros (only an '&' operator) or extra unused space for local unions. [The usual disclaimers go here.] david r. tribble univ. texas at arlington tribble_acn@uta