Path: csiph.com!news.mixmin.net!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Tim Rentsch Newsgroups: comp.lang.c Subject: Re: Command line globber/tokenizer library for C? Date: Mon, 16 Sep 2024 00:52:26 -0700 Organization: A noiseless patient Spider Lines: 81 Message-ID: <86y13savd1.fsf@linuxsc.com> References: <20240912181625.00006e68@yahoo.com> <20240912223828.00005c10@yahoo.com> <861q1nfsjz.fsf@linuxsc.com> <20240915122211.000058b1@yahoo.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Date: Mon, 16 Sep 2024 09:52:30 +0200 (CEST) Injection-Info: dont-email.me; posting-host="ed2c1c22c2facd770a4416268b44112b"; logging-data="2879767"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1++DlIdzQN9ssW8zafLggBjz6c57arJOt4=" User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux) Cancel-Lock: sha1:UIT57JJnLFPL6v09cuY+rmOjtts= sha1:rL0zaSnnLH4yaeXTxyIkF3pZxT8= Xref: csiph.com comp.lang.c:388407 Michael S writes: [comments reordered] > Also, while formally the program is written in C, by spirit it's > something else. May be, Lisp. I would call it a functional style, but still C. Not a C style as most people are used to seeing it, I grant you that. I still think of it as C though. > Lisp compilers are known to be very good at tail call elimination. > C compilers also can do it, but not reliably. In this particular > case I am afraid that common C compilers will implement it as > written, i.e. without turning recursion into iteration. I routinely use gcc and clang, and both are good at turning this kind of mutual recursion into iteration (-Os or higher, although clang was able to eliminate all the recursion at -O1). I agree the recursion elimination is not as reliable as one would like; in practice though I find it quite usable. > Tested on godbolt. > gcc -O2 turns it into iteration starting from v.4.4 > clang -O2 turns it into iteration starting from v.4.0 Both as expected. > Latest icc still does not turn it into iteration at least along one > code paths. That's disappointing, but good to know. > Latest MSVC implements it as written, 100% recursion. I'm not surprised at all. In my admittedly very limited experience, MSVC is garbage. > Can you give an example implementation of go->f() ? > It seems to me that it would have to use CONTAINING_RECORD or > container_of or analogous non-standard macro. You say that like you think such macros don't have well-defined behavior. If I needed such a macro probably I would just define it myself (and would be confident that it would work correctly). In this case I don't need a macro because I would put the gopher struct at the beginning of the containing struct. For example: #include typedef struct { struct gopher_s go; unsigned words; } WordCounter; static void print_word( Gopher go, const char *s, const char *t ){ WordCounter *context = (void*) go; int n = t-s; printf( " word: %.*s\n", n, s ); context->words ++; } int main(){ WordCounter wc = { { print_word }, 0 }; char *words = "\tthe quick \"brown fox\" jumps over the lazy dog."; words_do( words, &wc.go ); printf( "\n" ); printf( " There were %u words found\n", wc.words ); return 0; }