gostas@kuling.UUCP (G|sta Simil{/ml) (01/03/86)
I need to define a type for a program which can store any of the types long, int, short and also the unsigned variants of them. Some of the routines referencing this types will not use them directly however, it will use the sys/types.h typedefs dev_t, time_t etc. It will look something like this: "(*func)(&data)" there *func, but not the calling routine knows what type is currently stored in "data". The formal (but ugly) way to solve this would proparbly be to use a union for all (about 10) types. But now I wonder if anyone have a simpler but resonably portable solution? G|sta Simil{ gostas@kuling.UUCP
jsdy@hadron.UUCP (Joseph S. D. Yao) (01/05/86)
In article <870@kuling.UUCP> gostas@kuling.UUCP (G|sta Simil{/ml) writes: >The formal (but ugly) way to solve this would proparbly be to use a union >for all (about 10) types. But now I wonder if anyone have a simpler but >resonably portable solution? I really don't think you'll find any more portable solution than to use a union, which really isn't all that ugly if you declare the union elsewhere and use some good macros. E.g.: union mix { int mix_i; long int mix_li; dev_t mix_d; /* Be sure to include dev_t and */ time_t mix_t; /* time_t et al: they may surprise */ /* you. */ ... }; union mix getval(int); #define getint(x) (getval((x)).mix_i) #define getlong(x) (getval((x)).mix_li) ... If you're worried about portability, you certainly won't have any places where you don't know the type of the return value. Oh: to return a value, in the function you really should (e.g.): union mix getval(x) int x; { union mix retval; ... retval.mix_i = Xxx; return(retval); ... } which can be #define'd: #define retmix(val,type) retval.type = val; return(retval); => retmix(Xxx, mix_i); -- Joe Yao hadron!jsdy@seismo.{CSS.GOV,ARPA,UUCP}
gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) (01/06/86)
> I need to define a type for a program which can store any of the types > long, int, short and also the unsigned variants of them. > Some of the routines referencing this types will not use them directly > however, it will use the sys/types.h typedefs dev_t, time_t etc. > It will look something like this: "(*func)(&data)" there *func, > but not the calling routine knows what type is currently stored in "data". > The formal (but ugly) way to solve this would proparbly be to use a union > for all (about 10) types. But now I wonder if anyone have a simpler but > resonably portable solution? Since you're going to pass pointers, just coerce the actual data address into a generic pointer ((void *) if you have it, otherwise (char *)) and coerce it back inside the called function.
jsdy@hadron.UUCP (Joseph S. D. Yao) (01/06/86)
In article <168@hadron.UUCP> jsdy@hadron.UUCP (Joseph S. D. Yao) writes: >In article <870@kuling.UUCP> gostas@kuling.UUCP (G|sta Simil{/ml) writes: >>The formal (but ugly) way to solve this would proparbly be to use a union >>for all (about 10) types. But now I wonder if anyone have a simpler but >>resonably portable solution? > ... My original answer dealt with a union of outputs. Re-reading the message, it seems that you are talking about a union of inputs. Oh, well, the principle remains the same. I hope that you are relying on a state variable somewhere (even if it i s extern) to tell you what type the data is, rather than trusting the contents to let you know. -- Joe Yao hadron!jsdy@seismo.{CSS.GOV,ARPA,UUCP}
franka@mmintl.UUCP (Frank Adams) (01/07/86)
In article <1261@brl-tgr.ARPA> gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) writes: >> I need to define a type for a program which can store any of the types >> long, int, short and also the unsigned variants of them. >> Some of the routines referencing this types will not use them directly >> however, it will use the sys/types.h typedefs dev_t, time_t etc. >> It will look something like this: "(*func)(&data)" there *func, >> but not the calling routine knows what type is currently stored in "data". >> The formal (but ugly) way to solve this would proparbly be to use a union >> for all (about 10) types. But now I wonder if anyone have a simpler but >> resonably portable solution? > >Since you're going to pass pointers, just coerce the actual data >address into a generic pointer ((void *) if you have it, otherwise >(char *)) and coerce it back inside the called function. I got the impression he wanted long, short, etc. in his union, as well as pointers. If so, I don't think (void *) is portable; a long is bigger than any pointer on some machines. Frank Adams ihpn4!philabs!pwa-b!mmintl!franka Multimate International 52 Oakland Ave North E. Hartford, CT 06108
ken@gitpyr.UUCP (Ken Hall) (01/07/86)
May I ask a stupid question? Would somebody post or send me a very short C program that open a file, write something to it, then closes it? Thankyou in advance. Ken Hall
tribble_acn%uta.csnet@csnet-relay.arpa (David Tribble) (01/08/86)
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
kanner@tymix.UUCP (Herb Kanner) (01/09/86)
In article <1237@gitpyr.UUCP> ken@gitpyr.UUCP (Ken Hall) writes: >May I ask a stupid question? Would somebody post or send me a very short >C program that open a file, write something to it, then closes it? > >Thankyou in advance. #include <stdio.h> main() { FILE *file; filex = fopen("THING", "w"); /* opens file named THING for writing */ putc('a', filex); /* puts char 'a' in file pointed to by 'filex' */ fclose(filex); /* not necessary; end of program closes file */ } -- Herb Kanner Tymnet, Inc. ...!hplabs!oliveb!tymix!kanner
gostas@kuling.UUCP (G|sta Simil{/ml) (01/11/86)
In article <175@hadron.UUCP> jsdy@hadron.UUCP (Joseph S. D. Yao) writes: >In article <168@hadron.UUCP> jsdy@hadron.UUCP (Joseph S. D. Yao) writes: >>In article <870@kuling.UUCP> gostas@kuling.UUCP (G|sta Simil{/ml) writes: >>>The formal (but ugly) way to solve this would proparbly be to use a union >>>for all (about 10) types. But now I wonder if anyone have a simpler but >>>resonably portable solution? >> ... > >My original answer dealt with a union of outputs. Re-reading the >message, it seems that you are talking about a union of inputs. >Oh, well, the principle remains the same. > Joe Yao hadron!jsdy@seismo.{CSS.GOV,ARPA,UUCP} Yes, it's a union of inputs, no value will be returned and the calling program will have no idea what type the called functions are using currently, the code will look something like this: /* calling routine: */ typemix *base; /* malloc()'ed array, may change size during execution */ current_data = base; for (current_data = base; (something); current_data++, p++) if ((*p->function)(current_data)) /* value changed? */ (*p->action)(); /* really just a print routine */ /* called function: */ func(old_value) typemix *old_value; { some_type new_value = get_new_value(); if (new_value == old_value->some_type) return(0); old_value->some_type = new_value; return(1); } The example will be used when updating a screen, to avoid printing a field which have not changed value since the last update. G|sta Simil{ gostas@kuling.UUCP
gwyn@BRL.ARPA (VLD/VMB) (01/12/86)
A (long *) fits into a (void *) just fine.
zap@duvan.UUCP (Svante Lindahl) (01/14/86)
In article <1237@gitpyr.UUCP> ken@gitpyr.UUCP (Ken Hall) writes: >May I ask a stupid question? Would somebody post or send me a very short >C program that open a file, write something to it, then closes it? % cat > foo.c #include <stdio.h> main() { FILE *fopen(), *fp; if ((fp = fopen("/dev/tty","w")) == NULL) { (void) fprintf(stderr, "Can't open /dev/tty\n"); exit(1); } (void) fprintf(fp, "Go bye yourself a C-book!\n"); (void) fclose(fp); } % cc foo.c % a.out Go bye yourself a C-book! -- Svante Lindahl, NADA, KTH (Dept of Numerical Analysis and Computer Science at the Royal Institute of Technology) UUCP: {seismo,mcvax,cernvax,diku,ircam,prlb2,tut,ukc,unido}!enea!ttds!zap ARPA: enea!ttds!zap@seismo.ARPA or Svante_Lindahl_NADA%QZCOM.MAILNET@MIT-MULTICS.ARPA
zap@duvan.UUCP (Svante Lindahl) (01/14/86)
In article <1237@gitpyr.UUCP> ken@gitpyr.UUCP (Ken Hall) writes: >May I ask a stupid question? Would somebody post or send me a very short >C program that open a file, write something to it, then closes it? % cat > foo.c #include <stdio.h> main() { FILE *fopen(), *fp; if ((fp = fopen("/dev/tty","w")) == NULL) { (void) fprintf(stderr, "Can't open /dev/tty\n"); exit(1); } (void) fprintf(fp, "Go buy yourself a C-book!\n"); (void) fclose(fp); } % cc foo.c % a.out Go buy yourself a C-book!