Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!umich!samsung!think!snorkelwacker!spdcc!ima!haddock!karl From: karl@haddock.ima.isc.com (Karl Heuer) Newsgroups: comp.lang.c Subject: Re: Typeof operator in C (Re: An Interesting View of "Strong" Vs. "Weak" Typing) Summary: mostly off-topic rambling, marginally related Message-ID: <15671@haddock.ima.isc.com> Date: 17 Jan 90 00:45:39 GMT References: <16678@megaron.cs.arizona.edu> <7106@tank.uchicago.edu> <-K016ODxds13@ficc.uu.net> <5263@buengc.BU.EDU> <-121H63ggpc2@ficc.uu.net> <18180@umn-cs.CS.UMN.EDU> <5294@buengc.BU.EDU> Reply-To: karl@haddock.ima.isc.com (Karl Heuer) Organization: Interactive Systems, Cambridge, MA 02138-5302 Lines: 54 Note: |typeof(x)| already exists, with that name, in gcc; it is syntactically a type-name. To avoid confusion, I'll refer to the original concept (an operator that returns a value that somehow encodes the type information) as |typecode(x)|. >If it returns some integer, what does that integer mean, and what would you >do with it? My private library used to contain a function |void *alloc2(size_t, size_t)| which would return a heap pointer that could be used like a two-dimensional array. The idea was that (int **)alloc2(m, n*sizeof(int)) would allocate and return a single block of size m*sizeof(int *)+SLOP+m*n*sizeof(int), with the first portion initialized to point into the last portion. Then normal subscripting |a[i][j]| would work, and the whole mess could be returned to the freelist with a single call to |free()|. I stopped using this function when I realized that it could not be implemented on certain architectures. (I'm willing to use library functions that cannot be implemented portably, provided that they can be implemented nonportably on any individual machine. But this one can't be implemented *at all*, since there exist two distinct results that take the same input.) So instead I started writing the necessary expansion inline, and bemoaned the fact that this could never become a Standard Library function. Or could it? Suppose ANSI had mandated that a conforming implementation must provide a macro |TYPE **malloc2d(size_t nr, size_t nc, TYPE)|. Then a vaxlike architecture simply has this expand into |(TYPE **)alloc2(nr,nc*sizeof(TYPE))| where |alloc2()| is the function I described above. Would this mean that word-based architectures would be unable to implement ANSI C? No, all that they'd have to do is invent a minimal form of the |typecode()| operator, and use |(TYPE **)alloc2x(nr,nc*sizeof(TYPE),typecode(TYPE *))| as the expansion, where |alloc2x()| is like the impossible |alloc2()| except that it looks at the third argument to decide whether to use char pointers or word pointers when initializing the dope vectors. Note that it's not necessary for |typecode| to actually distinguish among the infinitely many types that can be constructed in C; all that is required *for this application* is that any two pointer types with "different internal representations" be distinguished. On any particular architecture there are a small number of these. Let's return to the question. >If it returns some integer, what does that integer mean, and what would you >do with it? If we were to agree that |typecode| is useful enough to actually require it (in my example it was a "magic builtin" that the user would never need to know about), I would say "implementation dependent". More precisely, it should return a value of type |typecode_t|, and it should be possible to compare two such values for equality. No other operations on |typecode_t| are necessary or desirable. Karl W. Z. Heuer (karl@haddock.isc.com or ima!haddock!karl), The Walking Lint