> [...] said, moving to fat function pointers on machines that don't > already use them is a real ABI change and therefore a big deal; but > it could be done if there were a compelling argument to justify going > through all the associated dark rituals.
Or as a private experiment, in which compatibility with other ABIs is irrelevant. That's what I would, putatively, be doing. > The conclusion over the past ~25 years has been that there isn't; > qsort and things like it work "well enough" and real uses for > closures that really motivate the feature come up rarely enough that > it doesn't happen. Nested functions are not closures, or at least not what I know as closures. A nested function pointer (conceptually) goes invalid as soon as anything it refers to goes out of scope, or at the latest as soon as its smallest enclosing block exits (or possibly when its smallest enclosing function returns). The thing I know as a closure would preserve the referred-to objects as long as the closure is potentially callable. This requires more reference tracking than C typically makes possible. > There is no solution based on trampolines that'll pass security (or > at least security-theatre) muster. Unless maybe by doing something > that's horrifying in other ways. The safest alternative that comes to my mind is to have two stacks, one for trampolines and one for everything else. But that requires something much like two stack pointers, including assist from the setjmp/longjmp implementation and, if applicable, threads. > (For example: you could declare a static limit on how many instances > of the closure you'll ever produce, make a global array to stuff the > data pointer in, and statically generate N trampoline entry points > that read from that array and call the primary function. But there > are many other ways in which this is horrible.) But there are use cases for which it is not a stupid implementation; for example, if no containing function is ever called recursively or reentrantly, and of course if the limit is high enough, it is obviously safe and quite possibly one of the fastest techniques available (since "creating" a trampoline can be made very fast, not needing even D$ pushes and I$ flushes). But, under those conditions, the autos in the enclosing function can be promoted to static storage duration and the nested function turned, essentially, into an ordinary function. Are the cases where the compiler can prove that's true a big enough fraction of the use cases to be useful? I don't know, not even for my own code. I _think_ one of the heavier uses of the technique - my ssh implementation - could work just fine with this approach, but I haven't looked at every nested function closely enough to be sure. (It needs more than nested functions, though; one of its uses of nested functions is to combine them with what gcc calls nonlocal gotos as a throw-out mechanism better in many respects than setjmp/longjmp.) /~\ The ASCII Mouse \ / Ribbon Campaign X Against HTML mo...@rodents-montreal.org / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B