Liste des Groupes | Revenir à cl c |
Michael S <already5chosen@yahoo.com> 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 <stdio.h>
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;
}
Les messages affichés proviennent d'usenet.