saito@slb-sdr.UUCP (Naoki Saito) (12/03/87)
A few weeks ago, there was a discussion on typeof() on this news group. I would like to use typeof() if someone has a code of that. What I want to do is to discriminate type of the structured variables. For example, typedef struct { float x; float y; } POINT; typedef struct { float r; float theta; } POINTR; foo(point) caddr_t *point; /* In fact, I don't know how to declare point here. */ /* caddr_t is "character address type" used in Sun. */ { if (typeof(*point) == POINT) { do something...} else if (typeof(*point) == POINTR) { do something...} } Could someone out there give me some suggestion/advise? Thanks in advance. Naoki Saito (saito%slb.sdr.com) Schlumberger-Doll Research
gwyn@brl-smoke.ARPA (Doug Gwyn ) (12/03/87)
In article <420@slb-sdr.UUCP> saito@slb-sdr.UUCP (Naoki Saito) writes: >foo(point) > caddr_t *point; /* In fact, I don't know how to declare point here. */ > /* caddr_t is "character address type" used in Sun. */ >{ > if (typeof(*point) == POINT) > { do something...} > else if (typeof(*point) == POINTR) > { do something...} >} What the above wants is impossible in principle, unless some sort of "dope vector" is used for parameter passing. Because dope vectors add non-negligible overhead, language implementors normally do not resort to them unless they're forced to. C is deliberately designed so as not to require such overhead on most architectures. There are two alternative approaches; first, with minimal changes to your example: /* ... typedefs unchanged */ foo(enum {POINT_T, POINTR_T} type, void *point) { if (type == POINT_T) {/* use ((POINT *)point) */} else if (type == POINTR_T) {/* use ((POINTR *)point) */} } or, what I would actually recommend: typedef struct { enum {POINT_T, POINTR_T} type; union { struct { float x; float y; } cartesian; struct { float r; float theta; } polar; } u; } coords; foo(coords *point) { if (point->type == POINT_T) {/* use point->u.cartesian.x etc. */} else if (point->type == POINTR_T) {/* use point->u.polar.r etc. */} }
barmar@think.COM (Barry Margolin) (12/04/87)
In article <420@slb-sdr.UUCP> saito@slb-sdr.UUCP (Naoki Saito) writes: > A few weeks ago, there was a discussion on typeof() on this news group. >I would like to use typeof() if someone has a code of that. >What I want to do is to discriminate type of the structured variables. >For example, > >typedef struct { > float x; > float y; >} POINT; > >typedef struct { > float r; > float theta; >} POINTR; > >foo(point) > caddr_t *point; /* In fact, I don't know how to declare point here. */ > /* caddr_t is "character address type" used in Sun. */ >{ > if (typeof(*point) == POINT) > { do something...} > else if (typeof(*point) == POINTR) > { do something...} >} If typeof existed, it would have to be built into the compiler, it couldn't be a library subroutine. And typeof(*point) would be caddr_t, not POINT nor POINTR. C doesn't have runtime data type tagging (a particular implementation could, but a program that depended on it would not be portable). The type of a variable is whatever it is declared to be. Stricly speaking, a caller of foo() is required to cast his POINT* or POINTR* parameter to caddr_t*, e.g. POINTR this_point; foo ((caddr_t *) &this_point); So even if the data type were passed in the call, it would pass caddr_t*, not the specific type. Someone else already responded suggesting passing an additional argument to foo to discriminate. An alternative would be to include a discriminant in your structure, e.g. typedef struct { enum {xy, rtheta} type; union {POINT, /* when type == xy */ POINTR} /* when type == rtheta */ } GENERAL_POINT; (please excuse any syntax errors, I don't do much C programming). Then instead of using typeof(point) you use point.type. --- Barry Margolin Thinking Machines Corp. barmar@think.com seismo!think!barmar
peter@sugar.UUCP (Peter da Silva) (12/05/87)
In article <420@slb-sdr.UUCP>, saito@slb-sdr.UUCP (Naoki Saito) writes: > foo(point) > caddr_t *point; > { > if (typeof(*point) == POINT) > { do something...} > else if (typeof(*point) == POINTR) > { do something...} > } Alas, but typeof(*point) (if there was such an operation) would be (caddr_t *). Do this: typedef struct { enum { POINT, POINTR } TYPE; union { struct { float x, y; } point; struct { float r, theta; } pointr; } DATA; } THING; foo(thing) THING thing; { if(thing.TYPE == POINT) do something with thing.DATA.point else if(thing.TYPE == POINTR) do something with thing.DATA.pointr } You have to maintain TYPE yourself. -- -- Peter da Silva `-_-' ...!hoptoad!academ!uhnix1!sugar!peter -- Disclaimer: These U aren't mere opinions... these are *values*.