Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!bbn!apple!oliveb!Ozona!chase From: chase@Ozona.orc.olivetti.com (David Chase) Newsgroups: gnu.gcc Subject: Re: address of labels Message-ID: <41161@oliveb.olivetti.com> Date: 29 Apr 89 01:09:10 GMT References: <8904282319.AA08492@riunite.aca.mcc.com> Sender: news@oliveb.olivetti.com Reply-To: chase@Ozona.UUCP (David Chase) Distribution: gnu Organization: Olivetti Research Center, Menlo Park, CA Lines: 62 rfg@MCC.COM (Ron Guilmette) writes: > >It is apparent that C is being used more and more as a kind of high-level >assembly language. > ... >One blatantly obvious feature seems to be missing however; i.e. the >ability to take the address of a label. Is there some way of doing >this in GCC that I don't know about? There's nothing provided with the language, no, but it is possible to hack it around to let you do this (I know; I did this very thing as an experiment). *However*, there's a bit of a gotcha or three: 1) I have no idea what interaction this would have with the rest of the back-end. What does this do for (to) optimization, for instance? 2) This interacts quite badly with some of the extensions made to GCC; in particular, the builtin goodies for dynamically allocating arrays on the stack within blocks. (Already you should have figured out that at a minimum a "label" is really a code address and a stack height.) (This is the answer that I got from RMS when I proposed this extension, by the way.) 3) If register allocation is at all sophisticated (I don't know what GCC is doing today), then it gets really messy; a "label" is not just an address, but a series of loads and stores (relative to where you come from, too) to ensure that the various registers contain what they are supposed to at that point. Of course, if register allocation is at all sophisticated you have to get pretty gung-ho with "volatile" to ensure that setjmp/longjmp allow your program to have any defined meaning at all, so (in an exception-handling context) this remains a problem. I use C as a "high-level assembly language" right now, and I can't say I'd do it again. It works great for a portability kit, but I wouldn't trust the use of an optimizing C compiler (setjmp and longjmp, and not enough volatile declarations yet) and the resulting code is dubiously debuggable. I don't get to use the implementation of choice for exceptions, and I'm stuck with the C compiler's idea of how floating point arithmetic "ought" to be done, and I can't even trust the compiler to do the right thing with returned structure values. The folks at Xerox PARC made it work for Cedar (debugging, that is), but it doesn't sound easy. One thing that they did differently (that I would emulate if I did it over again) was to generate exceptionally low-level C; it isn't portable, but it can be parameterized by machine type, and this avoids some really annoying problems with the C type system. ---------------- Another way to get the effect which you desire is to get a C compiler which performs tail-call elimination. In that way, you can get the effect of label variables by transforming a single procedure into a set of smaller procedures which pass around (say) a pointer to a structure containing the local variables (the whole thing needs to be wrapped up in something which allocates that structure, then passes it along). Instead of label variables, you use function variables. Of course, this might not provide the performance that you want, but, then, you did decide to use C as an assembler. David