Liste des Groupes | Revenir à cl c |
Michael S <already5chosen@yahoo.com> wrote:On Fri, 13 Sep 2024 09:05:04 -0700
Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
Michael S <already5chosen@yahoo.com> writes:
[..iterate over words in a string..]
I couldn't resist writing some code along similar lines. The
entry point is words_do(), which returns one on success and
zero if the end of string is reached inside double quotes.
typedef struct gopher_s *Gopher;
struct gopher_s { void (*f)( Gopher, const char *, const char * );
};
static _Bool collect_word( const char *, const char *, _Bool,
Gopher ); static _Bool is_space( char );
_Bool
words_do( const char *s, Gopher go ){
char c = *s;
return
is_space(c) ? words_do( s+1, go )
: c ? collect_word( s, s, 1, go )
: /***************/ 1;
}
_Bool
collect_word( const char *s, const char *r, _Bool w, Gopher go ){
char c = *s;
return
c == 0 ? go->f( go, r, s ), w
: is_space(c) && w ? go->f( go, r, s ), words_do( s, go )
: /***************/ collect_word( s+1, r, w ^ c == '"', go );
}
_Bool
is_space( char c ){
return c == ' ' || c == '\t';
}
<snip>
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
Latest icc still does not turn it into iteration at least along one
code paths.
Latest MSVC implements it as written, 100% recursion.
I tested using gcc 12. AFAICS calls to 'go->f' in 'collect_word'
are not tail calls and gcc 12 compiles them as normal call.
The other calls are compiled to jumps. But call to 'collect_word'
in 'words_do' is not "sibicall" and dependig in calling convention
compiler may treat it narmal call. Two other calls, that is
call to 'words_do' in 'words_do' and call to 'collect_word' in
'collect_word' are clearly tail self recursion and compiler
should always optimize them to a jump.
Les messages affichés proviennent d'usenet.